本文中我們将探索一種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的空間:

翻譯原文位址:
https://thelastpickle.com/blog/2016/12/08/TWCS-part1.html入群邀約
為了營造一個開放的 Cassandra 技術交流環境,社群建立了微信群公衆号和釘釘群,為廣大使用者提供專業的技術分享及問答,定期開展專家技術直播,歡迎大家加入。另外阿裡雲提供免費Cassandra試用:
https://www.aliyun.com/product/cds