クォーラム — 全員に聞かずに最新を保証する

レプリカが N 台あるとき、書込は W 台・読取は R 台の応答が集まれば完了とする。W + R > N ―― たった一行の不等式が「古い読み取り」を防ぐしくみを、集合の重なりを光らせながら確かめます。

1. 多数決の重なり — なぜ W + R > N で十分なのか

N 台全部に書き終わるのを待つと遅く、どれか1台が止まっただけで書込が止まります。逆に1台にだけ書くと、別の1台を読んだ人は古い値を見てしまう。そこで「書込は W 台に届けば成功、読取は R 台に聞けば成立」という部分集合方式にします。この W と R の組をクォーラム(定足数)と呼びます。

下のデモで W と R を動かしてみてください。読取集合はわざと「書込集合から一番遠い」最悪の選ばれ方にしてあります。それでも W + R > N なら必ず重なることが見えます。

重なり実験 — 最悪の選ばれ方でも重なるか?
青=最新 v2 を受け取った書込集合、オレンジ=読取で問い合わせる集合(最悪の配置)。緑に光るノードが両方に属する「重なり」。W+R を N 以下にすると重なりが消え、読取結果が古い v1 になります。W・R は N 台まで有効です。
POINT — 鳩の巣原理 書込集合(W 台)と読取集合(R 台)を合わせると W + R 台ぶんの「席」が要る。N 台しか無いのに W + R > N なら、どう選んでも最低 W + R − N 台は同じノードが両方の集合に入る。その重なったノードが必ず最新の値を持っている。
W + R > N 書込に成功した W 台と読取で聞く R 台は、合計が N を超えるかぎり必ず 1 台以上重なる。典型は N=3, W=2, R=2

2. 読み取りは「バージョンつき多数決」

重なるだけでは足りません。読取で集めた R 個の応答には古い値も混ざっているからです。そこで各書込に単調増加のバージョン番号(またはタイムスタンプ)を付け、応答の中でいちばん新しいバージョンを採用します。重なりが1台でもあれば、その1台が最新バージョンを運んでくるので正しい値が勝ちます。

読み取りの実際 — 古い応答が混ざっても最新が勝つ
N=5, W=3 固定。書込先・読取先は毎回ランダム
①書き手が W=3 台に新バージョンを書く → ②読み手が R 台に聞く → ③各ノードがバージョン付きで応答 → ④最大バージョンを採用。R を 2 以下(W+R≤N)にすると、書込集合と重ならない回に古い値を返してしまうのが観察できます。
注意 — W + R > N は万能ではない クォーラムを満たしても、2つのクライアントが同時に書くと衝突し得るし(同時書込の調停には W > N/2 やリーダー・バージョンベクトルが要る)、書込が W 台に届く途中で失敗すると中途半端な状態が残る。さらに障害時に代役ノードで数を合わせる緩いクォーラム(sloppy quorum)を使う設計では、重なりの保証そのものが崩れる。「厳密な最新読み保証」ではなく「古い読みを高い確率で防ぐ実用的なしくみ」と捉えるのが正確。

3. W と R をどう選ぶか — 速さと耐障害性のダイヤル

W + R > N を満たす組み合わせは1つではありません。書込は「W 番目に速い応答」が返った時点で完了するので、W が小さいほど書込が速い。読取も同様です。さらに、故障しても動き続けられる台数は書込側が N − W 台、読取側が N − R 台。つまり W と R はレイテンシと耐障害性を配分するダイヤルです。

(W, R) 設定くらべ — 完了タイミングと故障耐性
上段=5台の応答が届く時刻(点)と、W 台目・R 台目の応答で「完了」になる瞬間(点線)。下段=何台故障しても書込・読取を続けられるか。W=1 は書込が最速だが、読取が全台待ちになり1台の故障で読めなくなります。
書込は N − W 台、読取は N − R 台の故障まで継続できる N=5, W=3, R=3(過半数×過半数)なら、どちらも 2 台落ちても動き続けられる

4. 古いレプリカはどう直る? — 読み修復とアンチエントロピー

W < N で運用すると、書込のたびに N − W 台の「古いレプリカ」が生まれます。放置すればどんどん溜まるので、2つの掃除係が働きます。

掃除係の観察 — 読み修復+裏の同期
上の書き手が数秒ごとに3台へ書き、下の読み手が3台に聞きます。読取で古いノード(赤)が見つかると緑の「修復」パケットが飛ぶのが読み修復。紫の弧が裏で走る同期(アンチエントロピー)。OFF にすると、読取に当たらなかった古いレプリカが直りにくくなるのが分かります。
一歩先へ — 調整できる一貫性(tunable consistency) Dynamo の系譜(Cassandra・Riak・ScyllaDB など)は、クエリごとに W や R に相当する一貫性レベル(ONE / QUORUM / ALL)を選べる。「ログは W=1 で高速に、残高は QUORUM で堅く」のように、同じクラスタ内でデータごとに堅さと速さを配分できるのがクォーラム方式の実用上の強み。一方 ZooKeeper や etcd のような合意システムは常に過半数固定で、より強い保証(線形化可能性)を合意プロトコルで作る。

5. まとめ