时间戳有序数据上的Cassandra分页:通过群集密钥与本机分页进行过滤

时间:2016-11-03 16:33:14

标签: cassandra pagination

我有这样的表:

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. 在群集密钥上使用limit + filter: SELECT * FROM events_by_user WHERE user_id = :id AND date < :since LIMIT 10
  3. cassandra如何处理分区中的大量数据? 第二种方法似乎更灵活,因为数据可以按随机日期过滤。

2 个答案:

答案 0 :(得分:2)

第二种方法更有效,更灵活。 使用第一种方法,您无法跳到任何州,但可以使用第二种方式。

DataStax doc中的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    |
|------------------------------------|

答案 1 :(得分:1)

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

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

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

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

  3. 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消息的集合将包含at   大多数查询结果的第一行。如果说   结果的第一页包含查询的完整结果集   RESULT消息(种类Rows)将具有Has_more_pages标志   设置。但是,如果某些结果不是第一个响应的一部分,则将设置Has_more_pages标志,结果将是   包含一个值。在那种情况下,价值   应该在QUERY或EXECUTE消息中使用(具有相同的)   查询比原来的或行为是未定义的)   检索下一页结果。

           

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

           

      客户端实现者注意:

           
          
      • 虽然可以低至1,但可能会有害   绩效选择一个太低的价值。低于100的值也可能是   大多数用例都很低。
      •   
      • 客户端不应该依赖返回的结果集的实际大小   决定是否有更多的结果来获取。相反,他们应该永远   检查Has_more_pages标志(除非他们没有为查询启用分页   明显)。客户也不应声称没有结果会超过    结果。虽然目前的实施总是尊重   确切的价值,我们保留自己的返回权   由于性能原因,将来会略微缩小或缩小页面。
      •   
      • 特定于协议版本,驱动程序不应该   使用协议v3发送由节点返回的查询节点   例如,使用协议v4。
      •   
    2.