Mímisbrunnr知恵の泉

← 分散システム 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:合意問題とFLP不可能性 | 関連:Raft分散トランザクションとSaga

要点(BLUF)

問題設定 ── 全員一致でコミットしたい

銀行Aから引き、銀行Bへ足す。片方だけコミットされたら不整合。全ノードが同じ結末(commit/abort)に至ることが要る。これは合意問題(合意問題とFLP不可能性)の一種で、特に「全員賛成でなければabort」という強い条件付きです。

アルゴリズム ── 2PC の2フェーズ

sequenceDiagram
    participant C as コーディネータ
    participant P1 as 参加者1
    participant P2 as 参加者2
    Note over C,P2: フェーズ1: 準備(投票)
    C->>P1: prepare
    C->>P2: prepare
    P1-->>C: yes(commit可・ログ書込)
    P2-->>C: yes
    Note over C,P2: フェーズ2: 決定
    C->>P1: commit
    C->>P2: commit
    P1-->>C: ack
    P2-->>C: ack

正しさの観点 ── 安全性は守るが活性が弱い

flowchart LR
    Y["参加者:yesを返した(commit可・ロック中)"] --> D["コーディネータがクラッシュ"]
    D --> B["commit? abort? 不明 -> 永久ブロック"]

これは 合意問題とFLP不可能性 の「遅いと死んだが区別できない」が、ロック保持という形で牙を剥いた例です。

3PC ── 非ブロッキングの狙いと限界

3PCは準備とコミットの間に pre-commit フェーズを挟みます。「全員yes」を全員が知ってからコミットに進むので、コーディネータ故障時も参加者だけで結末を推論でき、ブロッキングを避けられます。ただし——ネットワーク分断が起きると、分断された両側が別々の結末(片方commit・片方abort)に進む危険があり、安全性を破りうる。さらにメッセージ往復が増えて遅い。このため実用では3PCはあまり使われません。

他手法との比較 ── 現代の解

方式ブロッキング分断耐性実用
2PCする単一コーディネータ前提なら今も広く使われる
3PCしにくい弱いほぼ使われない
2PC + コーディネータをRaft化実質しない強い現代の定番(Spanner等)
Saga(分散トランザクションとSagaしない(補償で巻き戻し)強いマイクロサービス向き

要するに「2PCのブロッキングはコーディネータが単一障害点だから」。コーディネータを合意(Raft)でレプリケーションすれば、落ちても別のコーディネータが結末を引き継げ、ブロッキングが消えます。

なぜ分散だと難しいか(直観)

「全員一致でコミット」は、一人でも音信不通になると進めない。準備完了後はもう引き返せない(ロック中)ので、コーディネータの沈黙が全員を人質にする。強い一貫を全ノードで保つ代償が、この脆さです。

⚠️ よくある誤解・落とし穴

対応ラボ

なし(概念回)。コーディネータ冗長化の核となるリーダー合意は Raft のラボで実証します。

関連

第5章 合意 目次