Cassandra 文件

版本

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

修復

Cassandra 旨在在其中一個節點關閉或無法連線時保持可用。但是,當節點關閉或無法連線時,它最終需要找出它錯過的寫入。提示會嘗試通知節點錯過的寫入,但盡力而為,並不保證會通知節點錯過的寫入 100%。這些不一致最終可能會導致資料遺失,因為節點被取代或墓碑到期。

這些不一致性會透過修復程序修復。修復會透過比較節點各自資料集的共同代幣範圍,並串流節點之間不同步區段的差異,來同步節點之間的資料。它會使用 Merkle 樹比較資料,Merkle 樹是雜湊層級。

增量修復和完整修復

有 2 種類型的修復:完整修復和增量修復。完整修復會針對要修復的代幣範圍中的所有資料進行操作。增量修復只會修復自上次增量修復以來寫入的資料。

增量修復是預設的修復類型,如果定期執行,可以大幅減少執行修復的時間和 I/O 成本。但是,了解一旦增量修復將資料標記為已修復,就不會再嘗試再次修復它,這一點很重要。對於同步錯過的寫入來說,這很好,但無法防止磁碟損毀、操作員錯誤導致資料遺失或 Cassandra 中的錯誤等問題。因此,仍應偶爾執行完整修復。

使用方式和最佳實務

由於修復可能會導致大量磁碟和網路 I/O,因此 Cassandra 沒有自動執行。它是由操作員透過 nodetool 執行的。

增量修復是預設值,並使用下列指令執行

nodetool repair

可以使用下列指令執行完整修復

nodetool repair --full

此外,可以在單一鍵值空間上執行修復

nodetool repair [options] <keyspace_name>

甚至可以在特定表格上執行

nodetool repair [options] <keyspace_name> <table1> <table2>

修復指令僅會修復正在修復的節點上的令牌範圍;它不會修復整個叢集。預設情況下,修復會針對節點上複製的所有令牌範圍執行,在每個節點上執行時會造成重複工作。使用 -pr 旗標僅修復節點上的「主要」範圍,以避免重複工作。在叢集中的每個資料中心中的每個節點上執行 nodetool repair -pr 指令,直到所有節點和資料中心都修復完畢,以執行完整叢集修復。

當然,適合叢集的特定修復頻率取決於多個因素。但是,如果您剛開始使用並正在尋找起點,那麼每 1-3 天執行一次增量修復,每 1-3 週執行一次完整修復可能是合理的。如果您不想執行增量修復,那麼每 5 天執行一次完整修復是一個不錯的起點。

至少應執行修復的頻率應足夠,以確保 GC 寬限期永遠不會在未修復的資料上到期。否則,已刪除的資料可能會重新出現。在 GC 寬限期預設為 10 天的情況下,至少每 7 天修復叢集中的每個節點一次,將可防止這種情況發生,同時提供足夠的餘裕來允許延遲。

其他選項

-pr, --partitioner-range

將修復限制為正在修復的節點的「主要」令牌範圍。主要範圍只是一個令牌範圍,節點是環中的第一個複本。

-prv, --preview

估計給定修復指令會發生的串流量。這會建立梅克爾樹並列印預期的串流活動,但實際上不會執行任何串流。預設情況下,會估計增量修復,新增 --full 旗標以估計完整修復。

-vd, --validate

驗證修復後的資料在所有節點上是否相同。與 --preview 類似,這會建立並比較修復後資料的梅克爾樹,但不會執行任何串流。這對於進行疑難排解很有用。如果這顯示修復後的資料不同步,則應執行完整修復。

nodetool 修復文件 <nodetool_repair>

完整修復範例

在增加鍵值空間的複本係數或將節點新增到叢集後,通常需要完整修復才能重新分配資料。完整修復涉及串流 SSTable。要示範完整修復,請從三個節點的叢集開始。

[ec2-user@ip-10-0-2-238 ~]$ nodetool status
Datacenter: us-east-1
=====================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address   Load        Tokens  Owns  Host ID                              Rack
UN  10.0.1.115  547 KiB     256    ?  b64cb32a-b32a-46b4-9eeb-e123fa8fc287  us-east-1b
UN  10.0.3.206  617.91 KiB  256    ?  74863177-684b-45f4-99f7-d1006625dc9e  us-east-1d
UN  10.0.2.238  670.26 KiB  256    ?  4dcdadd2-41f9-4f34-9892-1f20868b27c7  us-east-1c

建立一個具有複製因子 3 的鍵空間

cqlsh> DROP KEYSPACE cqlkeyspace;
cqlsh> CREATE KEYSPACE CQLKeyspace
  ... WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};

將表格新增到鍵空間

cqlsh> use cqlkeyspace;
cqlsh:cqlkeyspace> CREATE TABLE t (
           ...   id int,
           ...   k int,
           ...   v text,
           ...   PRIMARY KEY (id)
           ... );

新增表格資料

cqlsh:cqlkeyspace> INSERT INTO t (id, k, v) VALUES (0, 0, 'val0');
cqlsh:cqlkeyspace> INSERT INTO t (id, k, v) VALUES (1, 1, 'val1');
cqlsh:cqlkeyspace> INSERT INTO t (id, k, v) VALUES (2, 2, 'val2');

查詢會列出新增的資料

cqlsh:cqlkeyspace> SELECT * FROM t;

id | k | v
----+---+------
 1 | 1 | val1
 0 | 0 | val0
 2 | 2 | val2
(3 rows)

對三節點叢集進行下列變更

  1. 將複製因子從 3 增加到 4。

  2. 將第 4 個節點新增到叢集

當複製因子增加時,會輸出下列訊息,表示需要根據 (CASSANDRA-13079) 進行完整修復

cqlsh:cqlkeyspace> ALTER KEYSPACE CQLKeyspace
           ... WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 4};
Warnings :
When increasing replication factor you need to run a full (-full) repair to distribute the
data.

使用下列指令對鍵空間 cqlkeyspace 表格 t 執行完整修復

nodetool repair -full cqlkeyspace t

完整修復在約一秒內完成,如輸出所示

[ec2-user@ip-10-0-2-238 ~]$ nodetool repair -full cqlkeyspace t
[2019-08-17 03:06:21,445] Starting repair command #1 (fd576da0-c09b-11e9-b00c-1520e8c38f00), repairing keyspace cqlkeyspace with repair options (parallelism: parallel, primary range: false, incremental: false, job threads: 1, ColumnFamilies: [t], dataCenters: [], hosts: [], previewKind: NONE, # of ranges: 1024, pull repair: false, force repair: false, optimise streams: false)
[2019-08-17 03:06:23,059] Repair session fd8e5c20-c09b-11e9-b00c-1520e8c38f00 for range [(-8792657144775336505,-8786320730900698730], (-5454146041421260303,-5439402053041523135], (4288357893651763201,4324309707046452322], ... , (4350676211955643098,4351706629422088296]] finished (progress: 0%)
[2019-08-17 03:06:23,077] Repair completed successfully
[2019-08-17 03:06:23,077] Repair command #1 finished in 1 second
[ec2-user@ip-10-0-2-238 ~]$

nodetool tpstats 指令應列出已完成的修復,其中 修復任務 > 已完成 欄位值為 1

[ec2-user@ip-10-0-2-238 ~]$ nodetool tpstats
Pool Name Active   Pending Completed   Blocked  All time blocked
ReadStage  0           0           99       0              0
…
Repair-Task 0       0           1        0              0
RequestResponseStage                  0        0        2078        0               0