Cassandra 的壓縮策略STCS,LCS 和 DTCS


更新說明:
本文編寫時最新的Cassandra版本為2.2,最新的穩定版本為2.1.8
2016年6月23日,增加一篇譯文,當下最新版本為3.7

最新的Cassandra 2.1 或者更高的版本支持3種壓縮策略,各有優劣,在2.2的版本的說明文檔中,有對這三種策略的詳細說明,部分翻譯如下。
文檔鏈接:http://docs.datastax.com/en/cassandra/2.2/cassandra/dml/dmlHowDataMaintain.html?scroll=dmlHowDataWritten_unique_2__types-compaction

[TCS]

SizeTieredCompactionStrategy (STCS)

  • 推薦在寫密集負載中使用
  • 優勢:在寫密集的負載中工作良好
  • 劣勢:可能把舊數據數據保持太久。隨着時間的推移,需要的內存數量不斷增長。

實際使用中如果內存不是很充裕,容易因為SSTable合並過程占用過多內存,導致內存不足,其他節點的Message無法和當前節點交換,最終導致節點宕機。我們可能在cassandra-env.sh中配置了一些參數控制內存的使用,但是並不能限制數據壓縮的時候產生的內存損耗。多數建議是關閉自動SSTable壓縮,改用手動在空閑期間進行壓縮。

壓縮過程

當有(默認4個)SSTable的大小相似的時候,STCS便會啟動。壓縮過程將這些SSTable合並成一個大的SSTable。當大的SSTable積累了足夠數量,同樣的過程會再次發生,組合成更大的SSTable。在任何時候,一些不同大小的SSTable的存在都是暫時的。這種策略在寫密集的負載中工作良好,當需要讀數據的時候,需要嘗試讀取多個SSTable來找到一行中的所有的數據。策略無法保證同一行的數據被限制在一小部分的sstable中。同時可以預測刪除的數據是不均勻的,因為SSTable的大小是觸發壓縮的條件,並且SSTable可能增長的不夠快以便合並舊的數據。當最大的那些SSTable達到一定大小,合並需要的內存也會增長為同時容納新的SSTable+ 舊的SStable,可能會超出一個典型節點的內存總量。

LeveledCompactionStrategy (LCS)

  • 推薦在讀密集負載中使用
  • 優勢:內存的需求容易預測。讀操作的延遲可以預計。舊數據更快的被驅逐。
  • 劣勢:更高的io消耗可能引起操作延時。

實際上一般是又讀又寫,我覺得多數常見web應用可以用這個壓縮方式。

LCS意在解決一些STCS在讀操作上的一些問題。當SSTable的體積增長到一個不大的體積(默認5MB),它被寫入第0級,L0,並且馬上和第一級合並,L1。 在每個從L1開始的級別, 單個級別中所有的SSTable都確保沒有重復數據。因為沒有數據重復,LCS有時候會分割SSTable,就像合並他們時候一樣,以確保文件大小相同。每個級別都是上一個級別大小的10倍, 所以L1 將會是 L0 大小的10倍,而L2則是L0的100倍。當L1被填滿時L2就會開始被填入。由於每個級別沒有重復數據,所以一個讀操作可以在查找少數SSTable的情況下高效的完成。在許多讀操作中,最多需要讀取1~2個SSTable。事實上,90%的讀只需要讀取1個SSTable。最差的情況下是每個級別讀取一個SSTable(由於每個SSTable增長10倍體積,所以Level不會很多)。使用這個策略進行壓縮時候,需要的內存並不多,需要SSTable的10倍大小(50MB?)。過時的數據將會更快的被驅逐, 所以刪除的數據只會占據SSTable很小的一部分。 不過,LCS的壓縮方式出發的更頻繁,占據節點上更多的I/O。 在寫密集的的負載環境中,使用這種策略的收益不足以彌補I/O操作帶來的性能損失。在Cassandra 2.2 或者更高的版本中,當啟動一台新的LCS節點時候,旁路壓縮操作的優化已經被實施。原始數據被直接移動到正確的級別,因為之前沒有任何數據。performance improvements have been implemented that bypass compaction operations when bootstrapping a new node using LCS into a cluster. The original data is directly moved to the correct level because there is no existing data, so no partition overlap per level is present. For more information, see Apache Cassandra 2.2 - Bootstrapping Performance Improvements for Leveled Compaction.

有關LCS的更多介紹:http://www.datastax.com/dev/blog/leveled-compaction-in-apache-cassandra

DateTieredCompactionStrategy (DTCS)

  • Cassandra 2.0以后的版本才支持這個壓縮方式
  • 推薦使用在時間序列和需要生存時間管理的負載環境
  • 優勢:專為時間序列設計
  • 劣勢:非順序插入的數據會導致錯誤。在DTCS的情況下,讀修復必須關閉

DTCS和STCS很像,但是它不是基於SSTable的大小進行壓縮的,DTCS通過判斷SSTable的年齡(創建時間)進行壓縮。可配置的時間窗口確保新舊數據不會被混淆的合並到同一個SSTable。事實上,使用TTL時間戳,DTCS經常將包含過期數據的整個SSTable逐出。如果時間序列的輸出是穩定的,這個策略也會導致許多大小相似的SSTable。通過配置時間周期,SSTable會在一個確切的時間進行合並。如果一些SSTable 正好落在相同的時間區間內,SSTable仍然會合並為更大的table,就像STCS一樣。另外,如果SSTable達到了配置的年齡將不會進行壓縮,減少數據重復寫入的次數。使用這種策略壓縮的SSTable可以高效的讀取"last hour's worth of data",非常快。有個問題就是這種策略導致過期數據不容易寫入,比如一條記錄要寫入過期的時間。讀修復容易導致插入過期數據,所以需要關閉讀取修復。
For more information about compaction strategies, see When to Use Leveled Compaction and Leveled Compaction in Apache Cassandra. For DateTieredCompactionStrategy, see Date-Tiered Compaction in Cassandra or DateTieredCompactionStrategy: Compaction for Time Series Data.

更多關於DTCS http://www.datastax.com/dev/blog/datetieredcompactionstrategy
DTCS 的測試 http://jimplush.com/talk/2015/02/03/cassandras-datetieredcompaction-strategy-works-as-billed/

譯一篇有關DTCS的問題的的文章

作者開發了TWCS以規避DTCS的部分問題,但是並沒有全部被官方認同,不過正好幫助我認識DTCS的局限性

https://issues.apache.org/jira/browse/CASSANDRA-9666

DTCS 非常適合時序數據,但它的注意事項,使其難以在生產中的應用(一些典型的操作:bootstrap,removenode,repair 在max_sstable_age_days后不再合並,hints/read repair破壞了選擇算法)(譯:不知道指的是什么選擇算法)。

我提出一種替代方案,TimeWindowCompactionStrategy,它犧牲了DTCS的分層特性來彌補DTCS在操作上的一些缺陷。我相信有必要提出一種替代方案而不是調整DTCS,因為他基本上移除了分層特性以便移除max_sstable_age_days - 結果有很大不同,即使大量的參考了DTCS。

特別的,比起為增長的體積創建許多窗口(譯注:一個時間段),這個策略允許選擇窗口的大小,使用STCS壓縮第一個窗口,在這個窗口不是當前窗口的情況下,進一步將數據向下壓縮成一個SSTABLE。窗口的大小是一個混合的單位(分鍾,小時,天)和大小。這樣操作者可以認為所有的在窗口中的數據都壓縮在一起(比如你有個一個6小時的窗口,你每天會有4個sstable,每個SSTABLE 保存了大約6小時數據)

這個結果解決了許多DTCS的問題:

  1. 目前,DTCS的第一個窗口是按照一個選定的規則壓縮的,偏愛創建時間更早的文件,但是忽略體積。在TWCS(原文作者自己編寫的一個策略)中,第一個窗口數據將由更加成熟、快速的壓縮方案STCS。所有的的STCS選項都可以用於TWCS配置第一個窗口的壓縮行為。

HintedHandoff 可能導致舊數據被放到新的sstable,會導致輕微的性能損失(sstable將會覆蓋一個很大的范圍,但是舊的時間戳不會在壓縮的時候影響sstable的選擇標准)

ReadRepair 可能導致舊數據被放到新的sstable,會導致輕微的性能損失(sstable將會覆蓋一個很大的范圍,但是舊的時間戳不會在壓縮的時候影響sstable的選擇標准)

Small, old sstables resulting from streams of any kind will be swiftly and aggressively compacted with the other sstables matching their similar maxTimestamp, without causing sstables in neighboring windows to grow in size.

The configuration options are explicit and straightforward - the tuning parameters leave little room for error. The window is set in common, easily understandable terms such as “12 hours”, “1 Day”, “30 days”. The minute/hour/day options are granular enough for users keeping data for hours, and users keeping data for years.

There is no explicitly configurable max sstable age, though sstables will naturally stop compacting once new data is written in that window.

Streaming operations can create sstables with old timestamps, and they'll naturally be joined together with sstables in the same time bucket. This is true for bootstrap/repair/sstableloader/removenode.

It remains true that if old data and new data is written into the memtable at the same time, the resulting sstables will be treated as if they were new sstables, however, that no longer negatively impacts the compaction strategy’s selection criteria for older windows.

如何修改壓縮策略

創建的時候:

    CREATE TABLE use_view  (
    uid bigint PRIMARY KEY,
    ids map<int, int>
    ) WITH compaction = { 'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}

修改某個表的壓縮策略:

    alter table use_view WITH compaction = { 'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM