为什么cassandra count(*)在一个特定的分区上花费很长时间在相对较小的数据集上

8yparm6h  于 2021-06-10  发布在  Cassandra
关注(0)|答案(1)|浏览(416)

我有一个定义如下的表:
键空间: CREATE KEYSPACE messages WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true; 表格:

CREATE TABLE messages.textmessages (
    categoryid int,
    date timestamp,
    messageid timeuuid,
    message text,
    userid int,
    PRIMARY KEY ((categoryid, date), messageid)
) WITH CLUSTERING ORDER BY (messageid ASC);

我们的目标是拥有一个宽行时间序列存储,以便 categoryid 以及 date (一天的开始)构成我的分区键和 messageid 提供群集。这使我能够执行以下查询: SELECT * FROM messages.textmessages WHERE categoryid=2 AND date='2019-05-14 00:00:00.000+0300' AND messageId > maxTimeuuid('2019-05-14 00:00:00.000+0300') AND messageId < minTimeuuid('2019-05-15 00:00:00.000+0300') 在特定的一天里得到信息;它工作得那么好,那么快!
问题
我需要能够计数的信息,在一个给定的一天,通过替换 SELECT * 上面有 SELECT COUNT(*) . 即使列族中的条目略少于10万条,这也需要很长时间;它实际上是超时的 cqlsh .
我读了很多书,也明白了其中的原因 COUNT 对于像cassandra这样的分布式数据库来说,计算密钥是一项昂贵的操作吗?不如数星星
问题
为什么这个查询要花这么长时间,即使在:

SELECT COUNT(*) FROM messages.textmessages WHERE categoryid=2 AND date='2019-05-14 00:00:00.000+0300' AND messageId > maxTimeuuid('2019-05-14 00:00:00.000+0300') AND messageId < minTimeuuid('2019-05-15 00:00:00.000+0300')

计数在记录数少于100k的特定分区上
我只有一个高性能MacBookPro上的cassandra节点
示例中没有活动的写/读操作;笔记本电脑上的分区少于20个

ycl3bljg

ycl3bljg1#

这是可以理解的,因为一个常见的陷阱,当《Cassandra》中“一切都是书面的”的概念被忽视时,墓碑为什么会发生。
在分区内或分区之间执行扫描时,我们需要在内存中保留逻辑删除标记,以便将它们返回给协调器,协调器将使用它们来确保其他副本也知道已删除的行。对于生成大量逻辑删除的工作负载,这可能会导致性能问题,甚至耗尽服务器堆。
感谢@jimwartnick关于墓碑相关潜伏期的建议;这是由于我插入的大量墓碑 NULL 领域。我没有料到这会导致tombstones,也没有料到tombstones会对查询性能造成很大影响;尤其是 COUNT .
解决方案
在不存在时在字段中使用默认的未设置值,或者在插入/更新中完全忽略它们
认识到以下事实所概述的共同问题与Cassandra墓碑-阿拉巴基纳
一个常见的误解是,只有当客户机向cassandra发出delete语句时,墓碑才会出现。一些开发人员认为,选择一种依赖于完全没有墓碑的cassandra的操作方式是安全的。实际上,除了发出delete语句之外,还有许多其他的事情导致了墓碑。使用ttl插入空值、插入集合和过期数据是常见的逻辑删除源。

相关问题