我正在调试问题,日志应该位于4/23/19〜4/25/19之间的时间范围
我们的作品有数亿条记录。 使用随机排序无法找到目标记录。
在没有分区键的时间范围内是否可以进行搜索?
从XXXX.report_summary顺序中按*按Modify_at desc选择
...
"modified_at" "TimestampType" "regular"
"record_end_date" "TimestampType" "regular"
"record_entity_type" "UTF8Type" "clustering_key"
"record_frequency" "UTF8Type" "regular"
"record_id" "UUIDType" "partition_key"
答案 0 :(得分:2)
首先,ORDER BY
在Cassandra中确实是多余的。它只能在分区的 分区中的群集列上操作,然后只能对群集列的确切顺序进行操作。这样做的原因是,Cassandra从磁盘上顺序读取数据,因此它首先按照定义的群集顺序写入所有数据。
因此,IMO,Cassandra中的ORDER BY
毫无用处,除非您要更改排序方向(升/降)。
第二,由于其分布式特性,您需要采用面向查询的方法进行数据建模。换句话说,您的表必须设计为支持您打算运行的查询。现在您可以找到解决此问题的方法,但是基本上您是在分布式集群上进行全表扫描,这对任何人来说都不会很好。
因此,建议的解决方法是建立一个像这样的表:
CREATE TABLE stackoverflow.report_summary_by_month (
record_id uuid,
record_entity_type text,
modified_at timestamp,
month_bucket bigint,
record_end_date timestamp,
record_frequency text,
PRIMARY KEY (month_bucket, modified_at, record_id)
) WITH CLUSTERING ORDER BY (modified_at DESC, record_id ASC);
然后,此查询将起作用:
SELECT * FROM report_summary_by_month
WHERE month_bucket = 201904
AND modified_at >= '2019-04-23' AND modified_at < '2019-04-26';
这里的想法是,当您关心结果的顺序时,您需要按其他方式进行划分,以便进行排序。在此示例中,我选择了month,因此我将您的结果按月“存储”到了名为month_bucket
的分区键中。在每个月的时间里,我都以modified_at
结尾的顺序聚集在DESC
上。这样,最近的结果位于分区的“顶部”。然后,我投入record_id
作为平局键以帮助确保唯一性。
如果您仍然专注于以错误的方式执行此操作:
您实际上可以在当前架构上运行范围查询。但是,由于跨多个节点的“亿万条记录”,我对此寄予厚望。但是您可以使用ALLOW FILTERING
指令(您永远不要真正使用它)来实现它。
SELECT * FROM report_summary
WHERE modified_at >= '2019-04-23'
AND modified_at < '2019-04-26' ALLOW FILTERING;
此方法有以下警告:
ALLOW FILTERING
使Cassandra的工作方式并非真正设计出来的,所以我永远不会在生产系统上使用它。如果您确实需要运行这样的查询,建议您使用内存聚合工具,例如Spark。
另外,由于最初的问题是关于ORDER BY
的,所以我不久前写了一篇文章,更好地解释了这个主题:https://www.datastax.com/dev/blog/we-shall-have-order