修復
Cassandra は、いずれかのノードがダウンまたは到達不能になった場合でも、可用性を維持するように設計されています。ただし、ノードがダウンまたは到達不能になった場合、最終的には見逃した書き込みを検出する必要があります。ヒントは、ノードに見逃した書き込みを通知しようとしますが、最善の努力であり、ノードに見逃した書き込みの 100% を通知することを保証するものではありません。これらの不整合は、ノードが交換されたり、トゥームストーンの有効期限が切れたりすると、最終的にデータの損失につながる可能性があります。
これらの不整合は、修復プロセスによって修正されます。修復は、ノード間のデータの同期を、共通のトークン範囲に対するそれぞれのデータセットを比較し、ノード間で同期していないセクションの差分をストリーミングすることによって行います。データは、ハッシュの階層であるマークルツリーと比較されます。
増分修復とフル修復
修復には、フル修復と増分修復の 2 つのタイプがあります。フル修復は、修復対象のトークン範囲内のすべてのデータに対して動作します。増分修復は、前回の増分修復以降に書き込まれたデータのみを修復します。
増分修復はデフォルトの修復タイプであり、定期的に実行すると、修復の実行時間と IO コストを大幅に削減できます。ただし、増分修復によってデータが修復済みとしてマークされると、二度と修復を試みないことを理解することが重要です。これは、見逃した書き込みの同期には適していますが、ディスクの破損、オペレーターのエラーによるデータの損失、Cassandra のバグなどからは保護されません。このため、フル修復も時折実行する必要があります。
使用方法とベストプラクティス
修復は大量のディスクおよびネットワーク IO を発生させる可能性があるため、Cassandra によって自動的に実行されることはありません。nodetool を介してオペレーターによって実行されます。
増分修復はデフォルトであり、次のコマンドで実行されます。
nodetool repair
`nodetool repair`
nodetool repair --full
フル修復は、次のコマンドで実行できます。
nodetool repair [options] <keyspace_name>
`nodetool repair --full`
nodetool repair [options] <keyspace_name> <table1> <table2>
さらに、修復は単一のキースペースで実行できます。
`nodetool repair keyspace_name`
`nodetool repair keyspace_name table_name`
repair コマンドは、修復中のノードのトークン範囲のみを修復します。クラスタ全体を修復するわけではありません。デフォルトでは、修復は、修復が実行されているノードによってレプリケートされたすべてのトークン範囲で動作し、すべてのノードで実行すると重複した作業が発生します。 `-pr` フラグを使用して、ノードの「プライマリ」範囲のみを修復することで、重複した作業を回避します。クラスタ内の各データセンターの各ノードで `nodetool repair -pr` コマンドを実行し、すべてのノードとデータセンターが修復されるまで、フルクラスタ修復を実行します。
クラスタに適した修復の具体的な頻度は、もちろん、いくつかの要因によって異なります。ただし、始めたばかりで、どこから始めればよいかわからない場合は、1〜3日ごとに増分修復を実行し、1〜3週間ごとにフル修復を実行するのが妥当でしょう。増分修復を実行したくない場合は、5日ごとにフル修復を実行するのが適切です。
-
少なくとも、修復されていないデータで gc グレース期間が期限切れにならない程度に頻繁に修復を実行する必要があります。そうでない場合、削除されたデータが再び表示される可能性があります。デフォルトの gc グレース期間は 10 日であるため、クラスタ内のすべてのノードを少なくとも 7 日に 1 回修復することで、これを防ぎ、遅延に対応するための十分な余裕が生まれます。
その他のオプション
-
-pr, --partitioner-range
修復を、修復対象のノードの「プライマリ」トークン範囲に制限します。プライマリ範囲とは、ノードがリング内の最初のレプリカであるトークン範囲のことです。
-
-prv, --preview
指定された修復コマンドで発生するストリーミングの量を推定します。これはマークルツリーを構築し、予想されるストリーミングアクティビティを出力しますが、実際にはストリーミングを実行しません。デフォルトでは、増分修復が推定されます。 `--full` フラグを追加して、フル修復を推定します。
-vd, --validate
修復されたデータがすべてのノードで同じであることを確認します。 `--preview` と同様に、これは修復されたデータのマークルツリーを構築して比較しますが、ストリーミングは実行しません。これはトラブルシューティングに役立ちます。これが、修復されたデータが同期していないことを示している場合は、フル修復を実行する必要があります。
[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
nodetool repair docs <nodetool_repair>
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)
... );
フル修復は通常、キースペースのレプリケーション係数を増やした後、またはクラスタにノードを追加した後に、データを再配布するために必要です。フル修復には、SSTable のストリーミングが含まれます。フル修復を実証するには、3 ノードのクラスタから始めます。
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');
レプリケーション係数 3 でキースペースを作成します。
cqlsh:cqlkeyspace> SELECT * FROM t;
id | k | v
----+---+------
1 | 1 | val1
0 | 0 | val0
2 | 2 | val2
(3 rows)
`CREATE KEYSPACE cqlkeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};`
-
キースペースにテーブルを追加します。
-
`CREATE TABLE cqlkeyspace.t (k int PRIMARY KEY, v int);`
テーブルデータを追加します。
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.
`INSERT INTO cqlkeyspace.t(k, v) VALUES (1, 1);`
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 ~]$
`SELECT * FROM cqlkeyspace.t;`
[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