macOSへのCassandraのインストールと起動

macOSにHomebrewを使ってApache Cassandraをインストールし、起動・停止する手順をステップバイステップで解説します。

Apache Cassandraは、高い可用性とスケーラビリティを持つオープンソースのNoSQLデータベースです。ここでは、macOS環境にHomebrewを使ってCassandraをインストールし、起動する手順を解説します。

1. Cassandraのインストール

Homebrewがインストールされていることを前提とします。まだインストールしていない場合は、 Homebrewの公式サイト を参照してインストールしてください。

ターミナルを開き、以下のコマンドを実行してCassandraをインストールします。

brew install cassandra

このコマンドは、Cassandra本体と、Cassandraを操作するためのコマンドラインツール(cqlsh など)をインストールします。

2. Cassandraサーバーの起動

インストールが完了したら、以下のコマンドでCassandraサーバーを起動します。Homebrewの services コマンドを使用すると、バックグラウンドでCassandraをサービスとして起動・管理できます。

brew services start cassandra

Cassandraが正常に起動したか確認するには、以下のコマンドを使用します。

brew services list

cassandra のステータスが started になっていれば成功です。

3. CQLSH (Cassandra Query Language Shell) の起動

Cassandraが起動したら、cqlsh を使ってCassandraクラスターに接続し、CQL(Cassandra Query Language)コマンドを実行できます。

cqlsh

正常に接続できると、cqlsh> プロンプトが表示されます。

Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 6.0.0 | Cassandra 4.0.6 | CQL spec 3.4.5 | Native protocol v12]
Use HELP for help.
cqlsh>

これで、macOS上でCassandraの基本的な開発環境が整いました。

補足: Cassandraの停止と再起動

  • 停止:
    brew services stop cassandra
    
  • 再起動:
    brew services restart cassandra
    

4. 一貫性レベル(Consistency Level)のトレードオフをシミュレーションで確認する

Cassandraをインストールしただけでは、この分散データベースの本質であるチューナブル・コンシステンシー(読み書きごとに一貫性レベルを選べる仕組み)は体験できません。ここでは、実際にCassandraクラスタを組む代わりに、レプリケーション(RF=3)と一貫性レベル(ONE / QUORUM / ALL)の挙動をPythonで簡易シミュレーションし、実測値で挙動を確認します。

モデル化

レプリカ数 \(N=3\) とし、以下の2つの実験を行います。

(a) 読み取りレイテンシ vs 一貫性レベル コーディネータは読み取り要求をN台全レプリカに並行送信し、必要台数分(ONE=1台、QUORUM=2台、ALL=3台)の応答が揃った時点で読み取りを完了します。各レプリカの応答時間は対数正規分布(中央値2ms、σ=0.6)に従うと仮定し、これはデータセンター内ネットワーク+ディスクI/Oのジッタを模したものです。\(k\) 台目に必要な一貫性レベルの読み取りレイテンシは、\(k\) 番目に速い応答時刻(\(k\) -th order statistic)になります。

(b) write直後read競合でのstale read確率 書き込みはN台全てに送信され、コーディネータは最も速いW台からのackを受け取った時点で書き込み成功をクライアントに返します。この瞬間、コミットが速かったW台だけが新しい値を保持しています。直後(同時刻)にランダムなR台へ読み取りを発行したとき、そのR台の中に新しい値を保持するレプリカが1台も含まれなければ stale read(古い値を読んでしまう)となります。この確率は超幾何分布で厳密に計算でき、

\[ P(\text{stale}) = \frac{\binom{N-W}{R}}{\binom{N}{R}} \]

であり、\(R+W > N\) のとき \(N-W < R\) となるため分子が必ず0になり、理論的にstale readはゼロになります(これがCassandraの「R+W>Nなら強一貫性」という定説の中身です)。

シミュレーションコード

import numpy as np
from math import comb

rng = np.random.default_rng(42)
N = 3
TRIALS = 200_000

# (a) 読み取りレイテンシ: N台に並行リクエストし、k番目の応答到着時刻を取得
MEDIAN_MS, SIGMA = 2.0, 0.6
mu = np.log(MEDIAN_MS)
latencies = rng.lognormal(mean=mu, sigma=SIGMA, size=(TRIALS, N))
sorted_latencies = np.sort(latencies, axis=1)

for k, label in [(1, "ONE"), (2, "QUORUM"), (3, "ALL")]:
    lat_k = sorted_latencies[:, k - 1]
    print(label, "median=", np.median(lat_k), "p99=", np.percentile(lat_k, 99))

# (b) write直後read競合でのstale read確率(モンテカルロ)
def simulate_stale_probability(n_trials, n_replicas, W, R, rng):
    stale = 0
    for _ in range(n_trials):
        d = rng.random(n_replicas)          # 各レプリカのコミット順序
        order = np.argsort(d)
        updated_set = set(order[:W].tolist())              # 書き込みackを構成した最速W台
        read_set = set(rng.choice(n_replicas, size=R, replace=False).tolist())
        if updated_set.isdisjoint(read_set):
            stale += 1
    return stale / n_trials

def analytic_stale_probability(n_replicas, W, R):
    not_updated = n_replicas - W
    if R > not_updated:
        return 0.0
    return comb(not_updated, R) / comb(n_replicas, R)

実行結果

N=3、20万〜10万試行のモンテカルロシミュレーションで得られた実測値は以下の通りです。

(a) 読み取りレイテンシ(ms)

一貫性レベル中央値p95p99
ONE (k=1)1.222.453.22
QUORUM (k=2)2.003.875.12
ALL (k=3)3.277.1510.20

ONEからALLへ一貫性レベルを上げると、中央値レイテンシは約2.7倍、p99は約3.2倍に悪化しました。特にp99(テイルレイテンシ)の悪化が中央値より大きい点が重要で、「最も遅い1台に律速される」ALLの弱点が数値で確認できます。

(b) write直後read競合でのstale read確率(10万試行)

書き込みCL / 読み取りCLR+Wシミュレーション値理論値(超幾何分布)
ONE / ONE266.3%66.7%
ONE / QUORUM333.2%33.3%
QUORUM / ONE333.7%33.3%
ONE / ALL40.0%0.0%
QUORUM / QUORUM40.0%0.0%
ALL / ONE40.0%0.0%

シミュレーション値は理論値(超幾何分布)と誤差1%未満で一致しました。\(R+W \le N\) (ONE/ONE、ONE/QUORUM、QUORUM/ONE)では33〜66%という無視できないstale read確率が発生する一方、\(R+W > N\) を満たす組み合わせ(QUORUM/QUORUM、ONE/ALL、ALL/ONE)では10万試行中1件もstale readが発生しませんでした。これは「QUORUM書き込み+QUORUM読み取り」という実運用で最も一般的な設定が、読み取りコストをALLほど払わずに強一貫性を実質保証できることを裏付けています。

Cassandraの一貫性レベルシミュレーション結果:左は読み取りレイテンシ、右はwrite直後read競合でのstale read確率

まとめ

  • 一貫性レベルを上げるほど読み取りレイテンシ(特にp99)は悪化する(ONE比でALLは中央値2.7倍、p99は3.2倍)
  • \(R+W \le N\) の組み合わせはstale readを許容し、確率は超幾何分布 \(\binom{N-W}{R} / \binom{N}{R}\) で正確に予測できる
  • \(R+W > N\) を満たせば(QUORUM/QUORUMなど)、レイテンシの悪化を最小限に抑えつつstale readを理論上ゼロにできる

実際にクラスタを構築する際は、cqlsh でテーブル作成後に CONSISTENCY QUORUM; のようにセッション単位で一貫性レベルを切り替えて動作を確認してみてください。