0. いろいろ
Cassandra の特徴
- シェアードナッシング:マスターやスレーブが存在せず、すべてのノードは対等(単一障害点なし)。
- 高可用性
- リニアなスケーラビリティ:qps がノードの数に比例
- さまざまな言語をクライアントコードとしてサポート
バージョン2.x
Cassandra 2.x では、CQL、セキュリティ、およびパフォーマンスが大幅に強化された。
CQL for Cassandra 2.0.6では、
- 条件付き更新のバッチ処理
- 静的カラム
- クラスター化カラムのスライス取得の強化された制御
などの重要な機能が追加された。
読み込み・書き込みの特性
読み込み
読み込む時、クライアントは求めるデータのレプリカがどのノードにあるのかを知る必要がなく、どのノードにでも接続できる。クライアントが読み込みたいデータを持っていないノードに接続した場合、そのノードはトークンの範囲で識別可能なノードからデータを読み込むためにコーディネータノードとして機能する。
書き込み
memtable と SSTable のおかげでシーク操作やディスク読み込みがないため、書き込みが非常に高速。他の多くのデータベースと異なり、書き込みは全て追記。
1. アーキテクチャ
system キースペース
メタデータを保存する内部的なキースペース。 保持するメタデータ:
- ノードのトークン
- クラスタ名
- キースペースとスキーマ定義(動的なローディングをサポート)
- 移行データ
- ノードが起動しているかどうか
パーティショナー
クラスター内のノードにデータをどのように横断的に分散させるか、データの最初のコピーをどのノードに置くかを決定する。
ゴシッププロトコルと故障検出
- ゴシッププロトコル: ノード間で一定の間隔でランダムにコンタクトを行い、各ノードのデータ割り当て状況などを交換する。最大で3つのノードと通信し、自分の情報及びゴシップで得た他のノードの情報を交換するため、各ノードに全ノードの情報がすばやく知れ渡る。 クラスタ内の全ノードで同じシードノードリストを使用すれば、クラスタ内におけるゴシップ通信の分断を回避できる。
- ヒントハンドオフ: 書き込みの際にそのキーを担当するレプリカノードの一つが停止していた場合に、ヒント情報(障害中のノードに対して当該の書き込みを再実行する必要があることを示す)を稼働しているレプリカノードの一つに保存する機構。
- アンチエントロピー: データが最新の状態に保たれるように、ノード上のレプリカ・データを同期化すること。ヒントハンドオフとは異なり、手動で行う。
コミットログ, memtable, SSTable
-
コミットログ: Cassandra では、データの大半を各ノード上のメモリに保持する。ここへの書き込み操作を実行すると、即座に更新内容がディスク上のコミットログに書き込まれる。メモリ上の書き換えが失敗したとしてもデータのリカバリが可能であることを保障するため、コミットログに更新内容が書き込まれるまで、データの書き込みが成功したとは見なされない。 保存場所は cassandra.yaml で設定可能。
-
memtable: コミットログに書き込まれた後、値はメモリ上に常駐する memtable という構造に書き込まれる。この構造には、保持しておくオブジェクトの数の閾値があり、それを上回ると memtable 内のデータはディスク上の SSTable というファイルにフラッシュ(書き込み)される。
-
SSTable: memtable 上のデータがフラッシュされてできるディスク上のデータ構造。SSTable は不変で、アプリケーションからは変更できない。実際に保持しているデータは、
- インデックス キーに対応するデータの位置を保存(たぶん)
- ブルームフィルタ あるキーがデータファイルに存在するかをコンパクトに知るためのデータ。
- データファイル
で、はじめの2つは読み込みを高速化させるための仕組み。 ※ SSTable は Sorted String Table の略。String で保存されているわけではないのでちょっと不適切。 SSTable の保存場所も cassandra.yaml で設定可能。コミットログとは別の場所に設定することでパフォーマンスが向上する。
コンパクション
SSTable は複数のファイルに分けて保存されている。これを集約して、より効率の良い1つの SSTable に統合する操作がコンパクション(このとき、後述のトゥームストーンが付いたデータの削除も行われる)。 操作時には最大で対象ファイルと同じ空き容量が必要になるので、Cassandra のデータを保持するストレージ容量は想定ファイルサイズの2倍以上に保つ必要がある。 コンパクションの優先度を下げると、全体のパフォーマンスを向上させることができ、cassandra.in.sh に以下を追記するとディスク I/O の代わりに CPU 使用量が増加する。
-XX:+UseThreadPriorities \
-XX:ThreadPriorityPolicy=42 \
-Dcassandra.compaction.priority=1 \
nodetool を使えば、以下の操作も可能。
- コンパクションの一時的な停止
$ nodetool stop compaction
- コンパクション発生の閾値を取得
$ nodetool getcompactionthreshold
- コンパクション発生の閾値を設定
(以下の例だと全く発生しなくなる)
$ nodetool setcompactionthreshold 0 0
コンパクションを全く実行しない設定にすると、SSTable は集約されない。そのため、大量のデータ読み込みが行われるとパフォーマンスが低下する。また、Cassandra が大量のファイルディスクリプタを使用するため “too many open files” が発生する可能性がある。
トゥームストーン
RDBMS の論理削除に似た概念。Cassandra ではデータは即時には削除されない。削除操作は、値に対して目印(トゥームストーン)をつける更新操作として扱われる。実際の削除は、コンパクションの実行時に行われる。
スニッチ
各ノード間のネットワーク経路(ラックやデータセンターなどの物理位置や仮想位置)を定義する。これにより、リクエストを効率的にルーティングできる。デフォルトのSimpleSnitchは、データ・センターまたはラック情報を認識しない。 → 実働環境にはGossipingPropertyFileSnitch(ノードのデータセンターとラックを定義し、その情報を他のノードに伝えてくれる)が推奨される。
データセンター
Cassandra でいうデータセンターは、互いに関連のあるノードの集まりのこと。データセンターには、物理的なデータセンターと仮想データセンターがある。異なるワークロードごとに異なるデータセンターを使うと良い。レプリケーションはデータセンターごとに設定されるので、異なるデータセンターを使用することで、Cassandra のトランザクションが他のワークロードの影響を受けることを防げると同時に、互いに近いデータセンターで要求を処理することによってレイテンシーを下げることができる。
シードノード
新規のノードをクラスタに追加する際、新ノードを起動し、稼働させる役割を持つノード。その他、新ノードはシードノード経由でゴシップを開始して状態情報を取得したり、ノードリングのトポロジーを学習できる。複数あっても良いが、全てのノードをシードにするのはダメ。データセンターあたりに複数のシードを持つのがベストプラクティス(Cassandra 2.0 ドキュメント)。 単一障害点ではない。
コンシステント・ハッシュ法
- Cassandra では、パーティションキーからハッシュ値を計算し、その値に応じて実データを保存するノードを決定する。
- このハッシュ値は比較可能にしておき、各ノードには一定のハッシュ値の範囲を割り当てて該当するキーのデータを格納する。
- ノードの追加・削除に際して、自分の担当範囲に隣接する担当範囲を持つノードとやりとりして、データを移動させる。
何が嬉しいのか?
- 通常、ハッシュによるデータ分配では、ノード数 $n$ に対して $hash \mod n$ などを計算して格納先ノードを決めることが多い。
- これだとノードの追加や削除によって $n$ が変わり、全データの再分配が必要になる。
- コンシステントハッシュ法の場合、移動が起こるのは削除・追加されるノードの隣接ノードのみなので、データの移動が最小限に抑えられる。
パーティションキー
テーブルの PRIMARY KEY を複数指定した時、最初のキーがパーティションキー(どのノードにデータが配布されるかを決定する)になる。
CREATE TABLE sample_table (
entity text,
property text,
time int,
value text,
PRIMARY KEY (entity, property, time)
);
最初のキーの値の種類が少ない場合、ノードが持つデータ量に偏りが生じてしまう。 → 複合パーティションキーを使えば、複数キーをまとめてパーティションキーとみなしてデータを配布してくれる。
CREATE TABLE sample_table (
entity text,
property text,
time int,
value text,
PRIMARY KEY ((entity, property), time)
);
2. インストール
3. クラスターの初期化
4. セキュリティ
5. データベース内部の仕組み
6. 構成
7. 運用
8. バックアップと復元
9. Cassandra ツール
メモ
2.1.x より古いバージョンで DROP TABLE してから同じ名前のテーブルを作ると key cache のせいでクエリに対する応答がおかしくなる
https://support.datastax.com/hc/en-us/articles/204226339-FAQ-How-to-drop-and-recreate-a-table-in-Cassandra-versions-older-than-2-1