Cassandra 文件

版本

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

提示

提示是一種資料修復技術,應用於寫入作業期間。當複本節點無法接受變更時,可能是因為故障或更常見的例行維護,嘗試寫入這些複本的協調器會將暫時提示儲存在其本機檔案系統中,以便稍後應用於不可用的複本。提示是縮短資料不一致持續時間的重要方式。在不可用的複本節點返回環狀網路後,協調器會快速重播提示。然而,提示盡力而為,並不保證最終一致性,就像 反熵修復 一樣。

提示很有用,因為 Apache Cassandra 會如何複製資料以提供容錯性、高可用性和耐用性。Cassandra 透過一致性雜湊在叢集間分割資料,然後將金鑰複製到雜湊環上的多個節點。為了保證可用性,金鑰的所有複本都可以接受變更,而無需共識,但這表示某些複本可能會接受變更,而其他複本則不會。發生這種情況時,就會產生不一致性。

提示是三種方式之一,除了讀取修復和完整/增量反熵修復之外,Cassandra 實作最終一致性保證,即所有更新最終都會被所有複本接收。提示和讀取修復一樣,盡力而為,並非執行完整修復的替代方案,但它們確實有助於減少複本之間不一致的持續時間。

提示交接

提示手動移交是 Cassandra 將提示套用至不可用節點的程序。

例如,考慮在具有 3複製因子的鍵空間上以 一致性層級 LOCAL_QUORUM 進行變更。通常,用戶端會將變更傳送至單一協調器,然後協調器會將變更傳送至所有三個複本,且當三個複本中的兩個確認變更時,協調器會對用戶端回應成功。然而,如果複本節點不可用,協調器會將提示暫時儲存在檔案系統中,以供稍後套用。新的提示會保留最長達 max_hint_windowin_ms 的停機時間(預設為 3 h)。如果不可用的複本在視窗到期前返回叢集,協調器會套用任何待處理的提示變更至複本,以確保維持最終一致性。

Hinted Handoff in Action
  • (t0):用戶端傳送寫入,而協調器將其傳送至三個複本。不幸的是,replica_2 正在重新啟動,無法接收變更。

  • (t1):用戶端從協調器收到法定人數確認。此時,用戶端相信寫入是耐用的,且對讀取可見(事實上也是如此)。

  • (t2):在寫入逾時(預設為 2s)後,協調器判定 replica_2 不可用,並將提示儲存在其本機磁碟中。

  • (t3):稍後,當 replica_2 重新啟動時,它會向所有節點(包括協調器)傳送八卦訊息。

  • (t4):協調器會針對 replica_2 重新播放提示,包括錯失的變更。

如果節點未及時返回,目標複本將永久不同步,直到讀取修復或完整/增量反熵修復傳播變更為止。

提示套用

提示會以大量方式串流,一次一個區段,至目標複本節點,而目標節點會在本地重新播放它們。在目標節點重新播放一個區段後,它會刪除該區段並接收下一個區段。此動作會持續進行,直到所有提示都耗盡為止。

提示在磁碟上的儲存

提示儲存在協調器節點的 $CASSANDRA_HOME/data/hints 目錄中的平面檔案中。提示包括提示 ID、要儲存變更的目標複本節點、無法傳遞至複本節點的序列化變更(儲存為 blob)、變更時間戳記,以及用於序列化變更的 Cassandra 版本。預設情況下,提示會使用 LZ4Compressor 進行壓縮。多個提示會附加至同一個提示檔案。

由於提示包含原始未修改的變更時間戳記,因此提示套用是冪等的,且無法覆寫未來的變更。

逾時寫入要求的提示

也會為逾時的寫入要求儲存提示。cassandra.yaml 中的 write_request_timeout 設定會設定寫入要求的逾時時間。

write_request_timeout: 2000ms

協調器會等待已設定時間讓寫入要求完成,在該時間點會逾時並為逾時的請求產生提示。write_request_timeout 可接受的最低值為 10 毫秒。

設定提示

提示預設為啟用狀態,因為它們對於資料一致性至關重要。cassandra.yaml 設定檔提供多項設定來設定提示

表 1. 提示設定

設定 說明 預設值

hinted_handoff_enabled

啟用/停用提示性交接

true

hinted_handoff_disabled_datacenters

資料中心清單,即使交接已啟用,也不會執行提示性交接。範例

hinted_handoff_disabled_datacenters:
  - DC1
  - DC2

未設定

max_hint_window

定義節點在發生故障後產生提示的最大時間量。

3h

hinted_handoff_throttle

每秒每傳遞執行緒的最大頻寬限制,以 KiB 為單位。這將會根據叢集中的節點數成比例地減少。(如果叢集中有兩個節點,每個傳遞執行緒將會使用最大速率;如果有 3 個節點,每個節點將會節流到最大值的二分之一,因為預計兩個節點會同時傳遞提示。)

1024KiB

max_hints_delivery_threads

傳遞提示的執行緒數目;當您有跨資料中心部署時,請考慮增加這個數字,因為跨資料中心交接往往較慢

2

hints_directory

Cassandra 儲存提示的目錄。

$CASSANDRA_HOME/data/hints

hints_flush_period

提示應從內部緩衝區清除到磁碟的頻率。不會觸發 fsync。

10000ms

`max_hints_file_size

單一提示檔案的最大大小,以 MB 為單位。

128MiB

hints_compression

套用到提示檔案的壓縮。如果省略,提示檔案將會以未壓縮的方式寫入。支援 LZ4、Snappy 和 Deflate 壓縮器。

LZ4Compressor

使用 nodetool 在執行階段設定提示

nodetool 提供多個指令來設定提示或取得提示相關資訊。如果 cassandra.yaml 中有任何設定,nodetool 指令將會覆寫執行指令的節點之對應設定。

表 2. 提示的 Nodetool 指令

指令 說明

nodetool disablehandoff

停用儲存和傳遞提示

nodetool disablehintsfordc

停用儲存和傳遞提示到資料中心

nodetool enablehandoff

在目前節點上重新啟用儲存和傳遞提示

nodetool enablehintsfordc

啟用先前已停用的資料中心提示

nodetool getmaxhintwindow

列印毫秒為單位的最大提示視窗。Cassandra 4.0 新增功能。

nodetool handoffwindow

列印目前的提示移交視窗

nodetool pausehandoff

暫停提示傳遞程序

nodetool resumehandoff

繼續提示傳遞程序

nodetool sethintedhandoffthrottlekb

設定每個傳遞執行緒每秒的提示移交節流,單位為 kb

nodetool setmaxhintwindow

設定指定的毫秒為單位的最大提示視窗

nodetool statushandoff

目前節點上儲存未來提示的狀態

nodetool truncatehints

截斷本機節點上的所有提示,或截斷指定端點的提示。

讓提示在執行階段播放得更快

1024 kbps 移交節流的預設值對大多數現代網路來說過於保守,而且很有可能在單純的節點重新啟動中累積數 GB 的提示,可能需要數小時才能播放完畢。例如,如果您每個節點吸收 100 Mbps 的資料,重新啟動 10 分鐘就會產生 10 分鐘 * (100 megabit / 秒) ~= 7 GiB 的資料,而以 (1024 KiB / 秒) 的速度播放完畢需要 7.5 GiB / (1024 KiB / 秒) = 2.03 小時。確切的運算取決於負載平衡策略(循環比感知令牌更好)、每個節點的令牌數量(令牌越多越好),以及叢集的寫入速率,但無論如何,您可能都希望在執行階段增加此節流。

如果您發現自己處於這種情況,您可以考慮透過 nodetool sethintedhandoffthrottlekb 指令動態增加 hinted_handoff_throttle

允許節點在執行階段停機時間更長

有時節點可能會停機超過正常的 max_hint_window(預設為三小時),但硬體和資料本身仍然可以存取。在這種情況下,您可以考慮透過 Cassandra 4.0 中新增的 nodetool setmaxhintwindow 指令動態增加 max_hint_window (CASSANDRA-11720)。這將指示 Cassandra 繼續為停機端點保留提示更長的時間。

此命令應套用在叢集中可能持有提示的所有節點上。如有需要,可以透過設定 cassandra.yaml 中的 max_hint_window 設定,並隨後進行滾動重新啟動,以永久套用設定。

監控提示傳遞

Cassandra 4.0 新增直方圖,可了解傳遞提示需要多少時間,這對於作業員更精確找出問題很有用 (CASSANDRA-13234).

還有可供追蹤的指標,包括 Hinted Handoff <handoff-metrics> 和 Hints Service <hintsservice-metrics> 指標。