首页 > 解决方案 > 带有 TTL 的 Cassandra 墓碑

问题描述

我使用 cassandra 已经有一段时间了(DSE),我试图理解一些不太清楚的东西。我们为此插图运行 DSE 5.1.9。它是一个单节点集群(如果您有一个多节点集群,请确保 RF=nodeCount 以使事情变得更容易)。

这是非常简单的示例:创建以下简单表:

CREATE TABLE mytable (
    status text,
    process_on_date_time int,
    PRIMARY KEY (status, process_on_date_time)
) WITH CLUSTERING ORDER BY (process_on_date_time ASC)
AND gc_grace_seconds = 60

我有一段代码一次插入 5k 条记录,总共 200k 条记录,TTL 为 300 秒。状态总是“待定”,并且 process_on_date_time 是一个以 1 递增的计数器,从 1 开始(所有唯一记录 - 基本上是 1 - 200k)。

我运行代码,然后在完成后将内存表刷新到磁盘。只创建了一个 sstable。在此之后,没有压缩,没有修复,没有其他运行会创建或更改 sstable 配置。

在 sstable 转储之后,我进入 cqlsh,打开跟踪,将一致性设置为 LOCAL_ONE 并关闭分页。然后我重复运行它:

SELECT * from mytable where status = 'pending' and process_on_date_time <= 300000;

有趣的是我看到了这样的事情(为了便于阅读,删掉了一些文字):

Run X) Read 31433 live rows and 85384 tombstone cells (31k rows returned to my screen) 
Run X+1) Read 0 live rows and 76376 tombstone cells (0 rows returned to my screen - all rows expired at this point) 
Run X+2) Read 0 live rows and 60429 tombstone cells 
Run X+3) Read 0 live rows and 55894 tombstone cells 
... 
Run X+X) Read 0 live rows and 0 tombstone cells

到底是怎么回事?sstable 没有改变(显然因为它是不可变的),没有其他任何插入,刷新等。为什么墓碑计数减少直到它为 0?是什么导致了这种行为?

我希望看到每次运行:读取 100k 墓碑,并且查询中止,因为所有 TTL 在单个 sstable 中都已过期。

标签: cassandradatastax-enterprise

解决方案


对于其他可能对此答案感到好奇的人,我用 Datastax 打开了一张票,这是他们提到的:

在墓碑通过 gc_grace_seconds 之后,它们将在结果集中被忽略,因为它们在超过该点后被过滤掉。因此,您认为发布墓碑警告的唯一方法是让数据超过其 ttl 但仍在 gc_grace 内的假设是正确的。

并且由于它们被忽略/过滤掉,它们不会对系统产生任何有害影响,因为就像您说的那样,它们被跳过了。

所以这意味着如果 TTL 过期,但在 GC 宽限秒内,则在查询时它们将被计为墓碑。如果 TTL 过期并且 GC Grace Seconds 也过期,则它们不会被计为墓碑(跳过)。系统仍然必须“清除”过期的 TTL 记录,但除了处理时间之外,对查询没有“害处”。我发现这很有趣,因为我在任何地方都没有看到这个记录。

认为其他人可能对此信息感兴趣,如果他们的经历不同,可以添加它。


推荐阅读