CAP定理 — 分断のとき、何をあきらめるか
ネットワークはいつか必ず切れます。切れたその瞬間、システムは「一貫した答えを守って応答を拒む」か「応答を続けて食い違いを許す」かの二択を迫られる ―― CAP定理が言っているのはそれだけで、それ以上でもそれ以下でもありません。分断を起こして確かめます。
1. C・A・P の正確な定義
頭文字の意味を正確に押さえるところからです。日常語と少しずつずれています。
- C(一貫性 / Consistency) — 線形化可能性のこと。どのノードに読み書きしても、全体が「1台のマシン」のように振る舞い、古い値が見えない。
- A(可用性 / Availability) — 故障していないノードに届いたリクエストが、必ずエラーでない応答を得る。
- P(分断耐性 / Partition tolerance) — ノード間のメッセージが任意に失われても(=ネットワークが分断されても)システムが動き続ける。
2. 分断がないとき — C と A は両立する
まず平常時。書込はレプリカへ複製され、少し待てば全ノードが同じ値になります。どのノードも応答し(A)、複製完了を待ってから応答すれば古い値も見せない(C)。分断がなければ C と A は普通に両立します。トレードオフになるのは複製を「待つ時間」だけ ―― これは最後の節(PACELC)で回収します。
3. 分断 — 定理が牙をむく瞬間
スイッチ故障・ケーブル切断・過負荷。原因は何であれ、クラスタが互いに通信できない2つの島に割れることをネットワーク分断(network partition)と呼びます。分断が起きるかどうかはこちらでは選べません。選べるのは「起きたときにどう振る舞うか」だけです。
4. CP を選ぶ — 一貫性を守り、可用性を諦める
CP 側の設計は「古い値・食い違う値を絶対に見せない」を優先します。定番の実現方法は前レッスンでやった過半数(クォーラム): 全 5 台の過半数 = 3 台に届く側だけが読み書きを続け、届かない少数派はエラーを返します。エラーを返す=可用性の放棄ですが、二重の「真実」が生まれることはありません。
5. AP を選ぶ — 可用性を守り、あとで衝突を解決する
AP 側の設計は「とにかく応答を返し続ける」を優先します。分断中も両方の島が書込を受け付けるので、同じキーに別々の値が書かれ得ます。分断が直った瞬間にそれが衝突として発覚し、何らかのルールで解決しなければなりません。
6. PACELC — 分断がなくても残るトレードオフ
CAP は「分断中」しか語りません。しかし第2節で見たとおり、平常時にも「複製を待つほど一貫するが遅くなる」という綱引きがあります。これを含めて整理したのが PACELC です。
7. まとめ
- C は線形化可能性、A は「生きたノードが必ず応答」、P は分断への耐性。日常語より狭く正確な意味を持つ。
- 分断がなければ C と A は両立する。定理が二択を迫るのは分断が起きているあいだだけ。
- CP = 過半数側だけ継続し少数派はエラー(ZooKeeper・etcd・Spanner)。AP = 全部の島が受け続け、修復後に LWW やマージで衝突解決(Dynamo 系)。
- PACELC:分断中は A か C、平常時もレイテンシか一貫性か。設計の立場はこの2つの選択で言い表せる。