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