Cassandra:如何在没有EQ或IN限制的PRIMARY KEY的情况下使用'ORDER BY'?

Cassandra: How to use 'ORDER BY' without PRIMARY KEY restricted by EQ or IN?

我在 Scylla(Cassandra 兼容数据库)中有一个 table 定义如下:

create table s.items (time timeuuid, name text, primary key (time));

我想运行一个在特定时间后获取所有项目的查询,类似于以下内容:

select * from s.items where time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

但有人告诉我 ORDER BY is only supported when the partition key is restricted by an EQ or an IN. 要解决这个问题,我可以创建一个 table 并进行类似于以下的查询:

create table s.items (yes boolean, time timeuuid, name text, primary key (yes, time));

select * from s.items where yes=true and time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

虽然这可行,但它似乎不是最佳解决方案。由于我对 Scylla 和 CQL 还很陌生,有没有 better/proper 方法来做到这一点?

类似问题已得到解答。例如这里:Cassandra Data modelling : Timestamp as partition keys

您需要设计一个合适的分区键,可能是年份取决于预期的数据量

您添加一个布尔键并始终将其设置为“是”的解决方案基本上会创建一个包含所有数据的巨大分区。这很少是您真正想要的。如果这个分区是你的全部数据,这意味着即使你有一个 10 节点的集群,每个节点上有 8 CPUs,集群中所有 80 个节点中只有 3 CPUs做任何工作(因为每个分区都属于某个 CPU,并且 RF=3 时有三个副本)。

如果您想知道为什么您的原始解决方案不起作用并且 Scylla 拒绝 "ORDER BY",那么问题是尽管 Scylla 可以扫描整个 table 以查找之后的条目时间 X(您需要将 'ALLOW FILTERING' 添加到查询中),它没有有效的方法来 排序 它按时间找到的内容。在内部,不同的分区不是按分区键排序,而是按 "token",分区键的哈希函数排序。这种具有随机化效果的散列对于平衡集群上所有 CPU 之间的负载很重要,但会阻止 Scylla(或 Cassandra)以原始密钥顺序读取分区。

您可以做的一件事是按照 Alex 上面的建议,这是您的原始设置和建议的解决方案之间的中间地带:每个分区不要有一个项目,或者所有项目都在一个分区中,但中间有一些东西:例如,假设在您的工作负载中,您每天收集 100MB 的数据。所以你使用天数作为分区键(而不是你的 bool)。某一天的所有数据都将位于一个分区中。 每天的分区中,不同的条目(行)将按聚簇键顺序排序,即时间。使用此设置,要在特定日期之后检索所有项目,只需开始逐日查询即可。例如,查询第 134 天,然后是第 135 天,然后是第 136 天,然后……在每一天中,结果都已经排序。所以问题解决了。

此技术是一种相当著名的 "time series" 数据建模。 Scylla(和 Cassandra)甚至为此模型调整了一个特殊的压缩策略,TWCS(time-window 压缩策略)。