Cassandra 文件

版本

您正在檢視預發行版本的說明文件。

墓碑

什麼是墓碑?

Cassandra 刪除資料的程序旨在提升效能,並與 Cassandra 內建的資料分佈和容錯特性搭配使用。

Cassandra 將刪除視為插入,並插入稱為墓碑的時間戳記刪除標記。墓碑會經過 Cassandra 的寫入路徑,並寫入一個或多個節點的 SSTable。墓碑的主要特點差異在於它有內建的到期日期/時間。在到期期限結束時(寬限期),墓碑會在 Cassandra 的正常壓縮程序中刪除。

您也可以標記 Cassandra 列或欄位,並設定存活時間 (TTL) 值。在經過這段時間後,Cassandra 會使用墓碑標記物件,並像處理其他墓碑物件一樣處理它。

為什麼會有墓碑?

墓碑代表物件(列或欄位值)的刪除。這種方法會用於取代移除值,這是因為 Cassandra 的分佈式特性。一旦物件標記為墓碑,查詢會忽略所有早於墓碑插入時間戳記的值。

殭屍

在多節點叢集裡,Cassandra 可能會將相同資料的複本儲存在兩個或更多節點上。這有助於防止資料遺失,但會使刪除程序變得複雜。如果節點收到要刪除其本地儲存資料的命令,該節點會將指定物件標記為墓碑,並嘗試將墓碑傳遞給包含該物件複本的其他節點。但如果當時有一個複本節點沒有回應,它不會立即收到墓碑,因此它仍包含物件的刪除前版本。如果在該節點復原之前,已從叢集的其他部分刪除墓碑物件,Cassandra 會將復原節點上的物件視為新資料,並將其傳播到叢集的其他部分。這種已刪除但仍持續存在的物件稱為殭屍

寬限期

為了防止殭屍再次出現,Cassandra 會為每個墓碑設定寬限期。墓碑的寬限期使用表格屬性 ` WITH gc_grace_seconds` 設定。其預設值為 864000 秒(十天),在此之後,墓碑會過期,並可以在壓縮期間刪除。在寬限期到期之前,Cassandra 會在壓縮事件中保留墓碑。每個表格都可以針對此屬性設定自己的值。

寬限期的目的是讓沒有回應的節點有時間復原並正常處理墓碑。如果客戶端在寬限期內對墓碑物件寫入新的更新,Cassandra 會覆寫墓碑。如果客戶端在寬限期內傳送該物件的讀取,Cassandra 會忽略墓碑,並在可能的情況下從其他複本中擷取物件。

當沒有回應的節點復原時,Cassandra 會使用暗示移交來重播節點當機期間錯過的資料庫變更。在寬限期內,Cassandra 不会重播墓碑物件的變更。但如果節點在寬限期結束後才復原,Cassandra 可能會錯過刪除動作。

在墓碑的寬限期結束後,Cassandra 會在壓縮期間刪除墓碑。

刪除

gc_grace_seconds 過期後,墓碑可能會被移除(表示不再有任何物件已刪除某個特定資料)。但刪除的一個複雜因素是墓碑可能存在於一個 SSTable 中,而它標記為要刪除的資料存在於另一個 SSTable 中,因此壓縮也必須移除這兩個 SSTable。更精確地說,刪除實際的墓碑

  • 墓碑必須比 gc_grace_seconds 舊。請注意,即使 gc_grace_seconds 已過,墓碑也不會在壓縮事件之前被移除。

  • 如果分割區 X 包含墓碑,則包含該分割區的 SSTable 加上所有包含比包含 X 的墓碑更舊資料的 SSTable 都必須包含在相同的壓縮中。如果包含分割區 X 的任何 SSTable 中的所有資料都比墓碑新,則可以忽略它。

  • 如果啟用選項 only_purge_repaired_tombstones,只有在資料也已修復時,才會移除墓碑。此程序在「具有墓碑的刪除」區段中說明。

如果節點停機或斷線的時間超過 gc_grace_seconds,其已刪除的資料將修復回其他節點並在叢集中重新出現。這基本上與「沒有墓碑的刪除」區段中的內容相同。

沒有墓碑的刪除

想像一個三節點叢集,其中值 [A] 已複製到每個節點。

[A], [A], [A]

如果其中一個節點發生故障,而我們的刪除操作只移除現有值,我們最終可能會得到一個看起來像這樣的叢集

[], [], [A]

然後,修復操作會將 [A] 的值替換回缺少該值的兩個節點上。

[A], [A], [A]

這將導致我們的資料以殭屍的形式復活,即使它已被刪除。

具有墓碑的刪除

從一個三節點叢集重新開始,其中值 [A] 已複製到每個節點。

[A], [A], [A]

如果我們不移除資料,而是新增墓碑物件,因此單一節點故障的情況將如下所示

[A, Tombstone[A]], [A, Tombstone[A]], [A]

現在,當我們發出修復時,墓碑將被複製到副本,而不是復活已刪除的資料

[A, Tombstone[A]], [A, Tombstone[A]], [A, Tombstone[A]]

我們的修復操作會正確地將系統狀態設定為我們預期的狀態,其中物件 [A] 在所有節點上標記為已刪除。這表示我們最終會累積墓碑,而墓碑會永久累積磁碟空間。為了避免永久保留墓碑,我們為 Cassandra 中的每個資料表設定 gc_grace_seconds

完全過期的 SSTable

如果 SSTable 僅包含墓碑,並且保證 SSTable 沒有在任何其他 SSTable 中遮蔽資料,則壓縮可以刪除該 SSTable。如果您看到僅包含墓碑的 SSTable(請注意,一旦生存時間到期,TTL 資料就會被視為墓碑),但壓縮沒有將其刪除,則可能是其他 SSTable 包含較舊的資料。有一個名為 sstableexpiredblockers 的工具,可以列出哪些 SSTable 可以刪除,以及哪些 SSTable 阻擋它們被刪除。使用 TimeWindowCompactionStrategy,可以透過啟用 unsafe_aggressive_sstable_expiration 來移除保證(不檢查遮蔽資料)。