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