首页 > 解决方案 > Cassandra TOKEN 分页机制的问题

问题描述

我们的数据集有很多重复的分区键。我们正在使用 TOKEN 方法对数据进行分页。如果具有重复键的行被拆分到一个页面中,我们在下一次调用时不会得到剩余的重复项。

例如,假设我们有以下键:1 2 3 5 5 5 6 7 8,并且每个查询限制为 5 行。第一个查询“ select * from table where TOKEN(id) > TOKEN('') limit 5; ”按预期返回 1 2 3 5 5。第二个查询“ select * from table where TOKEN(id) > TOKEN('5') limit 5; ”返回 6 7 8。这不是我们想要的行为,我们希望第二个查询返回 5 6 7 8。考虑这,很明显为什么会发生这种情况:“ (TOKEN(id) > TOKEN('5') ”如果 id == 5 失败

我们做错了什么还是这就是它的工作方式?我们正在使用最新的 Java 驱动程序,但我认为这不是驱动程序问题,因为 Golang 驱动程序也表现出这种行为

我们(大部分)通过删除行集末尾的任何重复记录(示例中的 5 5)或删除最后一条记录(以涵盖最后一条记录在第二个中重复的情况)来解决该问题记录集)。如果记录集都是重复的,这将失败。显然,更大的限制会减少这种极端情况,但在生产环境中使用似乎并不安全。

*已编辑*

在 Stackoverflow 和网络其他地方的许多页面中都推荐使用 TOKEN 方法。但显然它不起作用:-(

@亚历克斯:

感谢您的回复。这个例子就是这个问题的一个简化例子。实际上,我们有 3000 万行,并且使用的限制为 1000。几年前首次设计表时,设计者不了解分区键的工作原理,因此他们使用用户 ID 作为分区,从而为我们提供了 3000 万个分区。我们认为这至少导致我们的修复时间过长(集群目前为 12 小时)。我们需要将整个表复制到具有不同分区键的新表中(在实时生产环境中)以解决分区键问题。此页面https://docs.datastax.com/en/developer/java-driver/2.1/manual/paging/似乎是一个更好的解决方案。

@纳达夫:

感谢您的回复。简单地删除限制将导致请求在我们软件的多个层中超时。上面的 DataStax 页面似乎是我们的最佳解决方案。

标签: javacassandra

解决方案


您不应该也不能使用令牌范围和 LIMIT 来翻阅结果,并且您自己发现它不起作用 - 因为 LIMIT 切断了一些结果,您无法继续。

相反,Cassandra 为您提供了一个单独的分页功能:您发出请求,获取前 1000(或其他)行以及一个“cookie”,您可以使用它恢复查询以获取下一页结果。请参阅您喜欢的驱动程序文档,了解以您喜欢的语言使用 Cassandra分页的语法。这不是“限制”——它是一个单独的功能。

将大型查询拆分为多个标记范围仍有其用途。例如,它允许您并行查询不同的范围,因为不同的令牌范围通常来自不同的节点。但是,您仍然需要使用分页查询每个范围以完成,并且不能使用“LIMIT”,因为您不知道每个范围有多少结果,需要全部阅读。


推荐阅读