【问题标题】:Cassandra paging on timestamp ordered data: filtering by clustering key vs native paginationCassandra 对时间戳有序数据进行分页:通过集群键过滤与本机分页
【发布时间】:2017-03-17 08:23:47
【问题描述】:

我有这样的桌子:

CREATE TABLE events_by_user (
   user_id text, 
   date timestamp,
   event_id text,
   event_data text,
   PRIMARY KEY ((user_id), date, event_id)
)
WITH CLUSTERING ORDER BY (date DESC, event_id ASC);

我想对其进行分页。 因此,查询模式可能是:选择前 10 个事件,选择后 10 个事件等等。 我在这里看到两个选项:

  1. 原生手动分页https://datastax.github.io/java-driver/manual/paging/
  2. 在集群键上使用限制 + 过滤器: SELECT * FROM events_by_user WHERE user_id = :id AND date < :since LIMIT 10

cassandra 将如何处理分区中的大量数据? 第二种方法似乎更灵活,因为可以按随机日期过滤数据。

【问题讨论】:

    标签: cassandra pagination


    【解决方案1】:

    第二种方法使用起来更高效、更灵活。 第一种方法不能跳转到任何状态,但第二种方法可以。

    DataStax 文档中的 First One 存在限制 The paging state can only be reused between perfectly identical statements (same query string, same bound parameters). Altering the contents of the paging state or trying to set it on a different statement will cause this method to fail.

    我已将 1000 万个事件与您的架构一起插入到单个用户 ID 中。
    这是表演

    |------------------------------------|
    | Driver Paging | Cluster Key Paging | 
    | --------------|--------------------|
    |  1345026 ms   |      1210296 ms    |
    |------------------------------------|
    

    【讨论】:

    • 谢谢。能否分享一下基准代码和示例数据?
    【解决方案2】:

    关于您的查询SELECT * FROM events_by_user WHERE user_id = :id AND date < :since LIMIT 10,它可能会导致您错过一些行——因为event_id 也用于集群键。 一个简单的例子是一个 user_id=,它只有一个 date= 和 100 行不同的 event_id(都使用相同的 date=)。在这种情况下,查询将返回前 10 行,而下一个查询将错过其余的不返回任何内容。

    分页由驱动程序以与您尝试执行的查询非常相似的方式完成,方法是传递额外的数据 paging_state。请注意:

    1. 分页不需要返回页面大小的结果 - 它可能返回更少,并且在返回结果时可能会考虑与性能相关的优化。

    2. 只要返回的行数等于限制,选项 2 的代码将继续读取下一页。在分区行除以限制请求的情况下(例如#rows % limits = 0),分页将需要更少的查询。在这些情况下,选项 2 中的最后一次迭代将需要尝试获取“下一页”并返回 0 行,而驱动程序可能会使用返回的额外位与数据标记没有额外的数据。

    https://git-wip-us.apache.org/repos/asf?p=cassandra.git;a=blob_plain;f=doc/native_protocol_v3.spec

    1. 结果分页

      该协议允许对查询结果进行分页。为此, QUERY 和 EXECUTE 消息的值 在 CQL3 行中指示所需的页面大小。

      如果为 提供正值,则结果 为查询返回的一组 RESULT 消息将包含在 大多数查询结果的第一行。如果说 结果的第一页包含查询的完整结果集, RESULT 消息(类型为Rows)将具有 Has_more_pages 标志 没有设置。但是,如果某些结果不是第一个响应的一部分,则会设置 Has_more_pages 标志并且结果将 包含一个值。在这种情况下,价值 应在 QUERY 或 EXECUTE 消息中使用(具有 same 查询比原始查询或行为未定义) 检索下一页结果。

      仅返回结果集的 CQL3 查询(带有 行kind) 支持分页。对于其他类型的查询, 值被忽略。

      客户端实现者注意事项:

      • 虽然可以低至 1,但很可能是有害的 以性能选择一个太低的值。低于 100 的值可能太 在大多数用例中较低。
      • 客户端不应依赖返回的结果集的实际大小 决定是否有更多结果要获取。相反,他们应该始终 检查 Has_more_pages 标志(除非他们没有为查询启用分页 明显地)。客户也不应该断言没有结果会超过 结果。虽然目前的实施总是尊重 的确切价值,我们保留退货的权利 出于性能原因,将来页面会稍微变小或变大。
      • 特定于协议版本,驱动程序不应 使用协议 v3 发送节点返回的 a 以查询节点 以协议 v4 为例。

    【讨论】:

      猜你喜欢
      • 2021-10-19
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 2019-07-22
      相关资源
      最近更新 更多