予備知識として、CassandraはReplicationFactorを定義することを思い出してください。それはキーと関連するカラムがいくつのノードに書き込まれるかを定義します。(Dynamoと同じように)Cassandraでは、書き込み時(削除時も含む)にいくつのレプリカをブロックするかを制御できます。具体的には、クラスタのReplicationFactorよりもConsistencyLevelを低く設定したりします。その場合、クライアントがアクセスしているサーバーノードは、いくつかのレプリカがダウンしていたり書き込みに応答しなかった場合でも、書き込みが成功した、と結果を返します。

(イベンチュアルコンシステンシー(結果整合性)の"イベンチュアル"のこと。もしも更新を受け取っていないレプリカを低いConsistencyLevelで読み込んだ場合、古いデータを読み込む可能性が有ります。CassandraはHintedHandoffReadRepairAntiEntropyを用いて、データが一貫していない時間を短くします。ConsistencyLevel.QUORUMのような高いレベルの一貫性も提供しますが、依然注意が必要です。)

したがって削除操作では、削除されようとしているデータのすべての痕跡をすぐに取り除くことができません。それが可能であるとすると、あるレプリカが削除操作を受け取らなかった場合、そのデータがもう一度利用可能になった際に、削除操作を受け取ったレプリカを更新ミスとして扱ってしまい、データを修復してしまいます! したがってCassandraでは削除時にデータを消去する代わりにTombstone(廃棄)と呼ばれる特別な値で置き換えます。Tombstoneは削除要求を受け取れなかったレプリカにも伝播されます。

もう一つ問題が有ります。Tombstoneとなったデータを削除するのに安全なタイミングをどのように知ることができるでしょうか? 完全に分散化された環境ではそれを知ることは不可能です。ZooKeeperのようなコーディネータを導入することはできますが、シンプルに保たれたデザインという原則からはずれてしまいます。複雑な運用 – モニターするのは1つのシステムだけで良いはずなのに、結局2つのシステムをモニターすること – になります。(これはZKが悪いソフトウェアだと言っているのではありません。 – 同じような機能を提供するものの中では最上でしょう。 – そもそも我々のシステムに含めたくない問題を解決するだけなのです。)

したがってCassandraでは、解決方法が不明な問題に直面した分散システム設計者がよく行う方法をとっています。つまり解決できる問題に変換するために、さらなる制約を定義することです。CassandraではGCGraceSecondsという定数を定義し、各ノードにそれぞれのローカルのTombstoneの年齢を追跡させます。そして定数値を超える時間が経過するとコンパクション時にGC可能だと判断します(MemtableSSTableを参照。)。ということはGCGraceSecondsよりも長い間ノードがダウンした場合、そのノードを故障したものとみなしてOperationsにある手順でノードを置き換えるべきです。デフォルトの設定はとても控えめで、10日間に設定してあります。ニーズに合ったAntiEntropyを設定すると、この値を短くすることができます。もちろんCassandraを1ノードで動かしている場合は0に設定することもできます。その場合、Tombstoneは最初のメジャーコンパクション時にGCされます。

https://c.statcounter.com/9397521/0/fe557aad/1/|stats

  • No labels