3

我正在尝试使用 fetch-size 使用 datastax-driver 分页。但是datastax文档说如下

请注意,设置提取大小并不意味着 Cassandra 将始终返回确切的行数,它可能会返回或多或少的结果

真的不知道分页实现的内部细节,但是有人可以澄清一下我们在什么情况下从服务器获得或多或少结果?例如,如果我将 fetch-size 设置为 10,则根据上述语句,可能会得到 8 或 12 行结果。但我想了解在什么情况下我们会收到 8 行(或 12 行)?

4

2 回答 2

4

请注意,设置提取大小并不意味着 Cassandra 将始终返回确切的行数,它可能会返回或多或少的结果

我不相信这个说法是完全正确的。您可以预期页面包含的页面大小可能小于所需的页面大小。例如,如果您的页面大小为 10,并且只有 8 行符合您的查询条件,那么您当然只能返回 8 行。

但是,我不熟悉服务器将在单个页面结果中发送回比页面大小更多的行的情况。机协议规范甚至指定返回的消息最多包含页面大小:

如果为result_page_size提供正值,则为查询返回的 RESULT 消息的结果集将最多包含查询结果的result_page_size第一行。

此外,协议规范还指出:

虽然当前实现始终尊重result_page_size的确切值,但出于性能原因,我们保留在未来返回稍微更小或更大的页面的权利。

我不认为这已经被执行了,但可以解释为什么驱动程序文档以这种方式表达。

于 2019-06-21T17:12:49.107 回答
2

安迪的回答相当完整,但我想补充一些关于为什么返回的页面不完全符合所需大小可能有用的见解 - 在当前或未来的实现中:

Cassandra 可能想要返回页面的原因之一是过滤。想象一下,该请求具有 ALLOW FILTERING,并且需要从磁盘读取大量数据只是为了生成几行,这些行最终通过过滤器并返回给客户端。客户端不知道这一点,请求了 1000 行的页面 - 但在我们的示例中,实际上可能生成 1000 行通过过滤器需要 10 秒,如果 Cassandra 在产生任何结果之前等待 10 秒,客户端将超时。所以在这种情况下,Cassandra 应该在超时之前返回它设法收集的任何行——即使这些只是 17 行而不是 1000 行。客户端将收到这 17 行,并正常恢复到下一页。

在极端情况下,可能有如此多的过滤工作而输出如此之少,以至于我们可能有很长时间甚至没有单行输出。在这种情况下,在超时之前,Cassandra 可能会返回一个结果为零的页面,该页面的 has_more 位打开,这意味着客户端应该继续分页(结果数量少于请求的数量 - 甚至为零 - 并不是什么时候开始的标志停止分页!)。我不确定今天 Cassandra 是否真的返回零行页面,但 Scylla(更快的 Cassandra 克隆)肯定会这样做,并且驱动程序应该记住使用 has_more 位作为何时停止分页的唯一标志。

另一个问题是为什么分页会返回更多比期望的行。正如安迪在回复中所说,我认为这实际上不会发生在卡桑德拉身上,也不会发生在斯库拉身上。但我可以理解为什么某些未来的实现可能希望它允许它发生:想象一个协调器需要 1000 行来显示一个页面。所以它从每个副本中最多读取 1000 行,但是存在不一致的数据,并且一个副本有额外的行,结果是协调器现在有 1001 行要返回。它可以(现在确实如此)只返回前 1000 行,但缺点是现在一些副本位于数据中的错误位置,当被要求读取下一页时需要重新找到它们的位置。如果我们返回了我们找到的所有 1001 行,所有副本都将能够从它们停止的确切位置有效地恢复它们的读取。

于 2019-06-23T09:47:52.167 回答