Cassandra Time Window Compaction Strategy (TWCS) :工作原理以及使用建议

本文中我们将探索一种Apache Cassandra中的新的compaction策略。我们将深入她的使用case、限制,并分享我们在生产环境中使用的经验。

Time Window Compaction Strategy : 工作原理以及使用建议

Cassandra使用LSM - tree 的引擎,这个引擎通过异步刷新不可变的数据块以sstable的形式落到磁盘上面以达到写入的高吞吐。随着时间推移,更多的sstable写入磁盘,最终会造成一个partition的数据存在于多个sstable中,降低了读写的性能。为了限制数据碎片,我们使用一个叫做compaction的进程去合并sstable。在cassandra中有一些可用的compaction策略可以达到合并的目的,这些策略是设计用来适应不同的数据模型和负载的。

Date Tiered Compaction Strategy (DTCS) 是在2014年被引入并希望降低写放大并变成了time series数据的compact策略标准。写放大是说数据被反复写入而不是仅仅一次。多次写入数据会造成I/O消耗,降低磁盘(比如ssd)的使用寿命且阻碍了别的进程对磁盘的使用。这个策略在实际环境中也有一系列自己的缺点,比如一些复杂的参数就让她很难推测使用。

在Crowdstrike工作的系统工程师Jeff Jirsa,同时现在是Cassandra的committer 以及PMC成员,创造了Time Window Compaction Strategy (TWCS)。

TWCS通过移除DTCS的分层特性来消除DTCS的一些缺点,而不是选择在时间窗口的sstable组上执行STCS。她使用sstable的最大时间戳而不是最小时间戳来决定哪个SStable属于哪个时间窗口。我们接下来详细介绍。

描述和行为

TWCS主要目的是通过创建彼此使用STCS策略合并的SStable的时间窗口的bucket来简化DTCS的策略。一个bucket里面的sstable不会和另一个bucket的sstable合并,这样就可以防止类似DTCS里面由于hints和repairs产生的写放大。

TWCS的继承了STCS的参数的简单形式:

CREATE TABLE twcs.twcs (
    id int,
    value int,
    text_value text,
    PRIMARY KEY (id, value)
) WITH CLUSTERING ORDER BY (value ASC)
    AND bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND gc_grace_seconds = 60
    AND default_time_to_live = 600
    AND compaction = {'compaction_window_size': '1', 
                      'compaction_window_unit': 'MINUTES', 
                      'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'}

上述表描述显示最终这个表会把同一分钟内的sstable文件使用STCS合成在一起,最终每一分钟存在一个文件。

下面是在磁盘上面观察到的我们的table使用1分钟bucket,一个10分钟的ttl以及一分钟的gc_grace_seconds。sstable只要大于STCS的个数阈值就会执行合并。

Ven  8 jul 2016 07:47:17 CEST
-rw-r--r--  1 adejanovski  staff  20567  8 jul 07:47 twcs-twcs-ka-1453-Data.db
=============
Ven  8 jul 2016 07:47:22 CEST
-rw-r--r--  1 adejanovski  staff  20567  8 jul 07:47 twcs-twcs-ka-1453-Data.db
-rw-r--r--  1 adejanovski  staff  21040  8 jul 07:47 twcs-twcs-ka-1454-Data.db
=============
Ven  8 jul 2016 07:47:27 CEST
-rw-r--r--  1 adejanovski  staff  20567  8 jul 07:47 twcs-twcs-ka-1453-Data.db
-rw-r--r--  1 adejanovski  staff  21040  8 jul 07:47 twcs-twcs-ka-1454-Data.db
=============
Ven  8 jul 2016 07:47:32 CEST
-rw-r--r--  1 adejanovski  staff  20567  8 jul 07:47 twcs-twcs-ka-1453-Data.db
-rw-r--r--  1 adejanovski  staff  21040  8 jul 07:47 twcs-twcs-ka-1454-Data.db
-rw-r--r--  1 adejanovski  staff  20856  8 jul 07:47 twcs-twcs-ka-1455-Data.db
=============
Ven  8 jul 2016 07:47:37 CEST
-rw-r--r--  1 adejanovski  staff  20567  8 jul 07:47 twcs-twcs-ka-1453-Data.db
-rw-r--r--  1 adejanovski  staff  21040  8 jul 07:47 twcs-twcs-ka-1454-Data.db
-rw-r--r--  1 adejanovski  staff  20856  8 jul 07:47 twcs-twcs-ka-1455-Data.db
-rw-r--r--  1 adejanovski  staff  20921  8 jul 07:47 twcs-twcs-ka-1456-Data.db
=============

然后STCS在07:47的窗口被触发,创建sstable1457:

Ven  8 jul 2016 07:47:37 CEST
-rw-r--r--  1 adejanovski  staff  89474  8 jul 07:47 twcs-twcs-ka-1457-Data.db
=============

在时间窗口bucket下面的别的sstable也会被flush到磁盘,最终会进行合并:

Ven  8 jul 2016 07:47:52 CEST
-rw-r--r--  1 adejanovski  staff  89474  8 jul 07:47 twcs-twcs-ka-1457-Data.db
-rw-r--r--  1 adejanovski  staff  20268  8 jul 07:47 twcs-twcs-ka-1458-Data.db
-rw-r--r--  1 adejanovski  staff  20804  8 jul 07:47 twcs-twcs-ka-1459-Data.db
=============
Ven  8 jul 2016 07:47:57 CEST
-rw-r--r--  1 adejanovski  staff  157411  8 jul 07:47 twcs-twcs-ka-1461-Data.db
=============
Ven  8 jul 2016 07:48:02 CEST
-rw-r--r--  1 adejanovski  staff  157411  8 jul 07:47 twcs-twcs-ka-1461-Data.db
-rw-r--r--  1 adejanovski  staff   21395  8 jul 07:48 twcs-twcs-ka-1462-Data.db
-rw-r--r--  1 adejanovski  staff  175158  8 jul 07:48 twcs-twcs-tmp-ka-1463-Data.db
=============
Ven  8 jul 2016 07:48:07 CEST
-rw-r--r--  1 adejanovski  staff  180903  8 jul 07:48 twcs-twcs-ka-1463-Data.db

sstable1463 是我们在7:47启动的第一个bucket的最后一个,并不会被新创建的sstable合并:

Ven  8 jul 2016 07:49:12 CEST
-rw-r--r--  1 adejanovski  staff  180903  8 jul 07:48 twcs-twcs-ka-1463-Data.db
-rw-r--r--  1 adejanovski  staff  203792  8 jul 07:49 twcs-twcs-ka-1475-Data.db
-rw-r--r--  1 adejanovski  staff   19670  8 jul 07:49 twcs-twcs-ka-1476-Data.db
=============
Ven  8 jul 2016 07:49:17 CEST
-rw-r--r--  1 adejanovski  staff  180903  8 jul 07:48 twcs-twcs-ka-1463-Data.db
-rw-r--r--  1 adejanovski  staff  203792  8 jul 07:49 twcs-twcs-ka-1475-Data.db
-rw-r--r--  1 adejanovski  staff   19670  8 jul 07:49 twcs-twcs-ka-1476-Data.db
-rw-r--r--  1 adejanovski  staff   19575  8 jul 07:49 twcs-twcs-ka-1477-Data.db
=============
Ven  8 jul 2016 07:49:22 CEST
-rw-r--r--  1 adejanovski  staff  180903  8 jul 07:48 twcs-twcs-ka-1463-Data.db
-rw-r--r--  1 adejanovski  staff  203792  8 jul 07:49 twcs-twcs-ka-1475-Data.db
-rw-r--r--  1 adejanovski  staff   19670  8 jul 07:49 twcs-twcs-ka-1476-Data.db
-rw-r--r--  1 adejanovski  staff   19575  8 jul 07:49 twcs-twcs-ka-1477-Data.db
-rw-r--r--  1 adejanovski  staff   19714  8 jul 07:49 twcs-twcs-ka-1478-Data.db
=============
Ven  8 jul 2016 07:49:27 CEST
-rw-r--r--  1 adejanovski  staff  180903  8 jul 07:48 twcs-twcs-ka-1463-Data.db
-rw-r--r--  1 adejanovski  staff  203792  8 jul 07:49 twcs-twcs-ka-1475-Data.db
-rw-r--r--  1 adejanovski  staff   86608  8 jul 07:49 twcs-twcs-ka-1480-Data.db
=============

过一会,我们可以看到每分钟一个sstable在磁盘上展现:

Ven  8 jul 2016 08:04:02 CEST
-rw-r--r--  1 adejanovski  staff  180903  8 jul 07:48 twcs-twcs-ka-1463-Data.db
-rw-r--r--  1 adejanovski  staff  203792  8 jul 07:49 twcs-twcs-ka-1475-Data.db
-rw-r--r--  1 adejanovski  staff  220004  8 jul 07:50 twcs-twcs-ka-1488-Data.db
-rw-r--r--  1 adejanovski  staff  199687  8 jul 07:51 twcs-twcs-ka-1500-Data.db
-rw-r--r--  1 adejanovski  staff  201276  8 jul 07:52 twcs-twcs-ka-1513-Data.db
-rw-r--r--  1 adejanovski  staff  223035  8 jul 07:53 twcs-twcs-ka-1525-Data.db
-rw-r--r--  1 adejanovski  staff  200849  8 jul 07:54 twcs-twcs-ka-1537-Data.db
-rw-r--r--  1 adejanovski  staff  222678  8 jul 07:55 twcs-twcs-ka-1550-Data.db
-rw-r--r--  1 adejanovski  staff  200856  8 jul 07:56 twcs-twcs-ka-1562-Data.db
-rw-r--r--  1 adejanovski  staff  200218  8 jul 07:57 twcs-twcs-ka-1575-Data.db
-rw-r--r--  1 adejanovski  staff  220425  8 jul 07:58 twcs-twcs-ka-1587-Data.db
-rw-r--r--  1 adejanovski  staff  199402  8 jul 07:59 twcs-twcs-ka-1599-Data.db
-rw-r--r--  1 adejanovski  staff  222336  8 jul 08:00 twcs-twcs-ka-1612-Data.db
-rw-r--r--  1 adejanovski  staff  198747  8 jul 08:01 twcs-twcs-ka-1624-Data.db
-rw-r--r--  1 adejanovski  staff  203138  8 jul 08:02 twcs-twcs-ka-1636-Data.db
-rw-r--r--  1 adejanovski  staff  219365  8 jul 08:03 twcs-twcs-ka-1649-Data.db
-rw-r--r--  1 adejanovski  staff  197051  8 jul 08:04 twcs-twcs-ka-1661-Data.db

当数据达到TTL(10分钟),他们变成tombstones(删除墓碑)。我们的表定义了tombstones可以在创建一分钟以后被清除。如果所有的数据都是在TTL内被创建的,sstable将会100%被丢弃,并将执行sstable的删除。

我们可以看到最老的sstable在数据过期以后被删除了:

Ven  8 jul 2016 08:07:27 CEST
-rw-r--r--  1 adejanovski  staff  220425  8 jul 07:58 twcs-twcs-ka-1587-Data.db
-rw-r--r--  1 adejanovski  staff  199402  8 jul 07:59 twcs-twcs-ka-1599-Data.db
-rw-r--r--  1 adejanovski  staff  222336  8 jul 08:00 twcs-twcs-ka-1612-Data.db
-rw-r--r--  1 adejanovski  staff  198747  8 jul 08:01 twcs-twcs-ka-1624-Data.db
-rw-r--r--  1 adejanovski  staff  203138  8 jul 08:02 twcs-twcs-ka-1636-Data.db
-rw-r--r--  1 adejanovski  staff  219365  8 jul 08:03 twcs-twcs-ka-1649-Data.db
-rw-r--r--  1 adejanovski  staff  197051  8 jul 08:04 twcs-twcs-ka-1661-Data.db
-rw-r--r--  1 adejanovski  staff  218333  8 jul 08:05 twcs-twcs-ka-1674-Data.db
-rw-r--r--  1 adejanovski  staff  203781  8 jul 08:06 twcs-twcs-ka-1686-Data.db
-rw-r--r--  1 adejanovski  staff  200753  8 jul 08:07 twcs-twcs-ka-1698-Data.db
-rw-r--r--  1 adejanovski  staff   88457  8 jul 08:07 twcs-twcs-ka-1703-Data.db

当bucket退出了当前时间窗口,他经历了一个major compaction,以达到最后每个bucket一个sstable的目的。如果这个当前的bucket是有效的,那么major compaction将始终执行。这个是对DTCS的max_sstable_age_days参数的重大改进,阻止了sstable到达这个参数并压缩从而使每一个cassandra集群在高吞吐下面最终留下数千个sstable。存在大量未compact的sstable的不好的地方是对于读取某个partition数据来说,需要查询每个sstable。虽然bloom filter是执行这种过滤的有效办法,但是还是必须执行数千次检测,对于低延时要求的读来说影响较大。

根据插入的TTL建议每个表bucket数量少于50,我们的表 twcs.twcs应该有一个不超过50分钟的TTL,90天的TTL会让我们选择3天的bucket:

CREATE TABLE twcs.twcs_90_days_ttl (
    id int,
    value int,
    text_value text,
    PRIMARY KEY (id, value)
) WITH CLUSTERING ORDER BY (value ASC)
    AND bloom_filter_fp_chance = 0.01
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
    AND comment = ''
    AND gc_grace_seconds = 60
    AND default_time_to_live = 7776000
    AND compaction = {'compaction_window_size': '3', 
                      'compaction_window_unit': 'DAYS', 
                      'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'}

注意compaction_window_size 的值是”分“,”小时“,”天“以便于简单的推理。sstable属于哪个bucket是取决于他的最高的时间戳。

这个设置给我们余下的保证:

  • 超过3天的数据不会被compact,更低的I/O消耗;
  • 在3天内的查询将会命中一些有限的sstable;
  • 使用TTL插入,tombstones会在文件删除时候被清理掉;
  • 由hint、repairs产出的数据将会被当前的时间窗口内合并,防止写放大;
  • 磁盘最大compaction是最新创建bucket的50%;
  • 磁盘使用率是容易预测的

负作用是out-of-window的repair将会把partition数据打散到多个bucket里面,他们将不会做合并。这是一个以防写放大的折中;

使用case

TWCS 就像DTCS一样是适用于time series数据的策略。更广泛的说他是适用于使用TTL的写过一次就不可变的情况。

她不是为在多个时间窗口中更新或显式删除的行而设计的,因为这将防止行在超过时间窗口阈值时被压缩在一起。

调整compaction特性

因为TWCS 依赖于STCS,标准的STCS 熟悉对于TWCS来说是有效的。

调整tombstone的删除

如果需要更积极的策略来回收磁盘空间和清理删除tombstone,那么可以将unchecked_tombstone_compaction设为true。如果TTL 是在一天内,那么tombstone_compaction_interval可以设置为TTL + gc_grace_seconds

考虑到TWCS应该是被用在无法改变的TTLed行上面,所以使用一个小的gc_grace_seconds很安全。

Major compaction

通过命令nodetool compact 可以执行major compact,major compaction 是把不同的文件合成一个,即使是不同bucket下面。

修改现有表到TWCS

可以通过下面的命令:

ALTER TABLE my_stcs_table 
WITH compaction = {'compaction_window_size': '1', 
                   'compaction_window_unit': 'DAYS', 
                   'class': org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'};

ALTER表以后,sstable将会以他们最大的时间戳为基准进行bucket的划分,在每一个bucket里面是以STCS进行合并。下面是使用LCST的表的sstable的列表:

macbook-pro:my_twcs_table-3cdb91f0474f11e6b3e6ad195cb1e991 adejanovski$ for f in *Data.db; do ls -lrt $f;echo 'Max timestamp : ' &&  date -r $(sstablemetadata $f | grep Maximum\ time | cut -d" "  -f3| cut -c 1-10) '+%m/%d/%Y %H:%M:%S'; done
-rw-r--r--  1 adejanovski  staff  1064128 11 jul 14:42 mb-5702-big-Data.db
Max timestamp : 
07/11/2016 14:41:53
-rw-r--r--  1 adejanovski  staff  1069630 11 jul 14:43 mb-5846-big-Data.db
Max timestamp : 
07/11/2016 14:43:18
-rw-r--r--  1 adejanovski  staff  1074573 11 jul 14:44 mb-5989-big-Data.db
Max timestamp : 
07/11/2016 14:44:43
-rw-r--r--  1 adejanovski  staff  1073635 11 jul 14:44 mb-5991-big-Data.db
Max timestamp : 
07/11/2016 14:44:43
-rw-r--r--  1 adejanovski  staff  1048760 11 jul 14:46 mb-6134-big-Data.db
Max timestamp : 
07/11/2016 14:46:08
-rw-r--r--  1 adejanovski  staff  29907 11 jul 14:46 mb-6135-big-Data.db
Max timestamp : 
07/11/2016 14:46:08
-rw-r--r--  1 adejanovski  staff  1052466 11 jul 14:47 mb-6277-big-Data.db
Max timestamp : 
07/11/2016 14:47:34
-rw-r--r--  1 adejanovski  staff  1056004 11 jul 14:49 mb-6421-big-Data.db
Max timestamp : 
07/11/2016 14:48:58
-rw-r--r--  1 adejanovski  staff  1071221 11 jul 14:57 mb-6542-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1049921 11 jul 14:57 mb-6543-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1057914 11 jul 14:57 mb-6546-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1057416 11 jul 14:57 mb-6548-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1057610 11 jul 14:57 mb-6549-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1054329 11 jul 14:57 mb-6550-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1056487 11 jul 14:57 mb-6551-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1064145 11 jul 14:57 mb-6553-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1057628 11 jul 14:57 mb-6554-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  702415 11 jul 14:57 mb-6556-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1056318 11 jul 14:57 mb-6557-big-Data.db
Max timestamp : 
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  577786 11 jul 14:57 mb-6629-big-Data.db
Max timestamp : 
07/11/2016 14:57:47

通过修改表属性为TWCS,一分钟以后目录变成:

macbook-pro:my_twcs_table-3cdb91f0474f11e6b3e6ad195cb1e991 adejanovski$ for f in *Data.db; do ls -lrt $f; echo 'Max timestamp :' && date -r $(sstablemetadata $f | grep Maximum\ time | cut -d" "  -f3| cut -c 1-10) '+%m/%d/%Y %H:%M:%S'; done
-rw-r--r--  1 adejanovski  staff  1064128 11 jul 14:42 mb-5702-big-Data.db
Max timestamp :
07/11/2016 14:41:53
-rw-r--r--  1 adejanovski  staff  1069630 11 jul 14:43 mb-5846-big-Data.db
Max timestamp :
07/11/2016 14:43:18
-rw-r--r--  1 adejanovski  staff  1052466 11 jul 14:47 mb-6277-big-Data.db
Max timestamp :
07/11/2016 14:47:34
-rw-r--r--  1 adejanovski  staff  1056004 11 jul 14:49 mb-6421-big-Data.db
Max timestamp :
07/11/2016 14:48:58
-rw-r--r--  1 adejanovski  staff  577786 11 jul 14:57 mb-6629-big-Data.db
Max timestamp :
07/11/2016 14:57:47
-rw-r--r--  1 adejanovski  staff  12654 11 jul 14:59 mb-6630-big-Data.db
Max timestamp :
07/11/2016 14:57:48
-rw-r--r--  1 adejanovski  staff  11276126 11 jul 14:59 mb-6631-big-Data.db
Max timestamp :
07/11/2016 14:56:55
-rw-r--r--  1 adejanovski  staff  1078628 11 jul 14:59 mb-6632-big-Data.db
Max timestamp :
07/11/2016 14:46:08
-rw-r--r--  1 adejanovski  staff  2148408 11 jul 14:59 mb-6633-big-Data.db
Max timestamp :
07/11/2016 14:44:43

我们可以看到有效的sstable都会被重新合并起来。把一个表的属性改成TWCS不需要准备什么太多的东西,特别是把STCS做转换,因为他们实际上很多的相似性。从LCST转换的话需要一些额外的工作,但是请放心当前的时间窗口具有一个更高的优先权并将占据所有有效的compaction槽位。属于老一点的bucket 的sstable会在当前bucket没有很充分的sstable的时候才会被压缩。

Bootstraping

Bootstrapping也会遵循相同的套路,每个bucket下面的所有的sstable都会compact到一起。

这个将会避免DTCS会出现的一个不好的点,那么就是达到max_sstable_age_days 的streamed sstable不会被合并。

Hints and repairs

为了避免写放大,TWCS使用sstable的最大时间戳用来划分每一个时间bucket。这种选择的一个警告是hints 以及read repair以及anti-entropy repair 会将属于老的bucket的数据与新bucket进行混合。

这回引入下面的缺点:

  • 在新创建sstable前,可能无法收回某些tombstone;
  • 在特定修复partition上面的读取可能会因为命中更多的bucket/sstable而造成更高的延时

tombstone的警告可以通过调整单个sstable的压缩策略来减轻。

Timestamp overlaps

使用sstablemetadata 工具以及一些脚本命令可以观察我们的sstable的输出:

for f in *Data.db; do meta=$(sudo sstablemetadata $f); echo -e "Max:" $(date --date=@$(echo "$meta" | grep Maximum\ time | cut -d" "  -f3| cut -c 1-10) '+%m/%d/%Y') "Min:" $(date --date=@$(echo "$meta" | grep Minimum\ time | cut -d" "  -f3| cut -c 1-10) '+%m/%d/%Y') $(echo "$meta" | grep droppable) ' \t ' $(ls -lh $f | awk '{print $5" "$6" "$7" "$8" "$9}'); done | sort

上面会列出所有以最大时间戳排序的sstable,并给我们最小时间戳以及估算的tombstone比例。

下面是对真实使用TWCS集群的命令的输出结果:

ax: 10/04/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.9490505651577649        31G Oct 31 05:30 myks-mytable-ka-232963-Data.db
Max: 10/05/2016 Min: 10/04/2016 Estimated droppable tombstones: 0.9560987002875797        38G Oct 31 10:03 myks-mytable-ka-233129-Data.db
Max: 10/06/2016 Min: 10/04/2016 Estimated droppable tombstones: 0.9481618753615573        36G Oct 30 21:05 myks-mytable-ka-232429-Data.db
Max: 10/07/2016 Min: 10/04/2016 Estimated droppable tombstones: 0.9521717448567388        38G Oct 30 18:26 myks-mytable-ka-232273-Data.db
Max: 10/08/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.95585602260063            38G Oct 30 13:16 myks-mytable-ka-232101-Data.db
Max: 10/09/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.949381410220861            33G Oct 30 09:00 myks-mytable-ka-232018-Data.db
Max: 10/10/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.9559645399027142        39G Oct 30 07:32 myks-mytable-ka-231925-Data.db
Max: 10/11/2016 Min: 10/04/2016 Estimated droppable tombstones: 0.950634006146064            35G Oct 31 07:11 myks-mytable-ka-233032-Data.db
Max: 10/12/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.9486612959756701        35G Oct 31 02:20 myks-mytable-ka-232740-Data.db
Max: 10/13/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.9554470308141092        38G Oct 30 22:34 myks-mytable-ka-232493-Data.db
Max: 10/14/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.949693885678604            36G Oct 30 18:20 myks-mytable-ka-232277-Data.db
Max: 10/15/2016 Min: 10/03/2016 Estimated droppable tombstones: 0.9557383456090225        37G Oct 30 13:33 myks-mytable-ka-232100-Data.db
Max: 10/16/2016 Min: 10/05/2016 Estimated droppable tombstones: 0.9504753169563435        81G Oct 17 10:45 myks-mytable-ka-217230-Data.db
Max: 10/17/2016 Min: 10/04/2016 Estimated droppable tombstones: 0.4789361839518767        85G Oct 18 13:19 myks-mytable-ka-218505-Data.db
Max: 10/18/2016 Min: 10/04/2016 Estimated droppable tombstones: 0.26920166792514394        84G Oct 19 05:44 myks-mytable-ka-219298-Data.db
Max: 10/19/2016 Min: 10/18/2016 Estimated droppable tombstones: 0.2398632806404871        82G Oct 20 08:53 myks-mytable-ka-220668-Data.db
Max: 10/20/2016 Min: 10/19/2016 Estimated droppable tombstones: 0.2345777170103667        81G Oct 21 09:43 myks-mytable-ka-221815-Data.db
Max: 10/21/2016 Min: 10/20/2016 Estimated droppable tombstones: 0.23166383913432712        83G Oct 22 09:56 myks-mytable-ka-222971-Data.db
Max: 10/22/2016 Min: 10/21/2016 Estimated droppable tombstones: 0.22872970980627125        81G Oct 23 09:59 myks-mytable-ka-224097-Data.db
Max: 10/23/2016 Min: 10/22/2016 Estimated droppable tombstones: 0.26338126235319065        81G Oct 24 06:17 myks-mytable-ka-224961-Data.db
Max: 10/24/2016 Min: 10/23/2016 Estimated droppable tombstones: 0.22151053801117235        82G Oct 25 11:28 myks-mytable-ka-226389-Data.db
Max: 10/25/2016 Min: 10/24/2016 Estimated droppable tombstones: 0.22783088210413793        80G Oct 26 09:56 myks-mytable-ka-227462-Data.db
Max: 10/26/2016 Min: 10/25/2016 Estimated droppable tombstones: 0.21954613750782576        80G Oct 27 11:32 myks-mytable-ka-228663-Data.db
Max: 10/27/2016 Min: 10/26/2016 Estimated droppable tombstones: 0.21810718139671728        81G Oct 28 11:20 myks-mytable-ka-229793-Data.db
Max: 10/28/2016 Min: 10/27/2016 Estimated droppable tombstones: 0.2263842889481549        83G Oct 29 09:47 myks-mytable-ka-230858-Data.db
Max: 10/29/2016 Min: 10/28/2016 Estimated droppable tombstones: 0.21774533904969468        82G Oct 30 11:32 myks-mytable-ka-232030-Data.db
Max: 10/30/2016 Min: 10/29/2016 Estimated droppable tombstones: 0.21695190527031055        81G Oct 31 11:06 myks-mytable-ka-233114-Data.db
Max: 10/31/2016 Min: 10/30/2016 Estimated droppable tombstones: 0.2590062225892238        6.4G Oct 31 02:00 myks-mytable-ka-232914-Data.db
Max: 10/31/2016 Min: 10/31/2016 Estimated droppable tombstones: 0.2573703764996242        119M Oct 31 10:53 myks-mytable-ka-233223-Data.db
Max: 10/31/2016 Min: 10/31/2016 Estimated droppable tombstones: 0.25738010877995654        82M Oct 31 11:03 myks-mytable-ka-233227-Data.db
Max: 10/31/2016 Min: 10/31/2016 Estimated droppable tombstones: 0.25771639853000644        1.8G Oct 31 10:39 myks-mytable-ka-233213-Data.db

具有0.9个可以删除的tombstone的sstable都是可以全部删除的,且tombstone都已经超过gc_grace_second,但是事实上还是有很多没有被删除。

仔细观察时间戳,我们可以发现最老的sstable在10/03有一个最小的时间戳,他是与myks-mytable-ka-232101-Data.db的sstable重叠的,后者与myks-mytable-ka-218505-Data.db 、 myks-mytable-ka-219298-Data.db重叠。最后2个还没有完全过期,这将组织删除与他们重叠的所有的sstable,这是因为cassandra安全检查以避免删除的数据再次出现。

这种情况下,我们不得不再等2天直到所有冲抵的sstable都过期,这样就可以回收470G以上的空间。

Deletions(删除)

TWCS不适合对非TTLed的数据进行删除的这种情况。考虑到来自不同窗口的sstable不会压缩到一起,因此在第一天插入并在第二天删除的数据将会使tombstone以及shadowed cells 位于不同的时间窗口中。除非执行major compact,并且在运行查询时删除操作应该是有效的,不然磁盘的空间不会被回收。如果需要的话,删除是可以在未完成的数据上执行的,但是这会造成partition位于不同的时间窗口之中,这会将延迟磁盘上数据的删除,直到两个时间窗口都过期。

摘要

DTCS不能提供可预期的结果,但是他是TWCS的父代,并允许产生一种压缩策略,这种策略既容易推了也允许在磁盘使用以及压缩负载上有很大的可预测性。TWCS很适合time series数据,但是对于不可变的TTLed数据是最适合的。

建议禁止TWCS表的读修复,并使用一种有侵略性的tombstone清除策略,因为读期间的摘要不匹配的话会触发读修复。这会不可避免的在多个时间窗口创建重叠,从而防止删除完全过期的sstable,直到重叠的sstable达到过期执行的100%。

在我们的几个客户集群种,从DTCS到TWCS的实际切换在cpu使用量,i/o减少,读延时和逻辑删除方面都有很大的提升。这使得TWCS的压缩策略在合适的负载下是可以推荐考虑的。

下面是一个示例,我们在几个小时内将sstable的数量从1000多减少到50个,并收回小几百G的空间:

Cassandra Time Window Compaction Strategy (TWCS) :工作原理以及使用建议

翻译原文地址:https://thelastpickle.com/blog/2016/12/08/TWCS-part1.html

入群邀约
为了营造一个开放的 Cassandra 技术交流环境,社区建立了微信群公众号和钉钉群,为广大用户提供专业的技术分享及问答,定期开展专家技术直播,欢迎大家加入。另外阿里云提供免费Cassandra试用:https://www.aliyun.com/product/cds
Cassandra Time Window Compaction Strategy (TWCS) :工作原理以及使用建议

上一篇:关于Apache Cassandra :快照技术


下一篇:Cassandra监控运维介绍