🎓 レベル:標準 | 重要度:A(必須)
📎 前提:分散システムとは・なぜ難しいか | 関連:分散コンピューティングの誤謬(8つの誤謬)・合意問題とFLP不可能性
要点(BLUF)
- 障害モデルは「ノードや通信がどう壊れうるか」を仮定として固定する枠組み。アルゴリズムの正しさは常に特定の障害モデルの下でしか主張できない。
- 強さの階層:クラッシュ ⊂ オミッション ⊂ タイミング ⊂ ビザンチン。右ほど弱い仮定=悪条件で、対処に必要な冗長度(ノード数)も増える。
- 目安:クラッシュ耐性は N≧2f+1(過半数が生存)、ビザンチン耐性は N≧3f+1(悪意ノードがf台でも合意可能)。
問題設定 ── 「壊れ方」を決めないと正しさを語れない
「このアルゴリズムは正しい」は無意味で、「この故障の仮定の下で正しい」が正しい言い方。たとえばPaxos/Raft(Paxos・Raft)はクラッシュ故障は耐えるが、嘘をつくノード(ビザンチン)は想定しません。だから最初に「相手はどう壊れるか」を固定します。
モデル ── 故障の型と強さの階層
弱い仮定(=より多くの壊れ方を許す)ほど、対処は難しくなります。
| 故障モデル | ノードの振る舞い | 例 | 包含 |
|---|---|---|---|
| クラッシュ(停止) | 正しく動くか、止まって二度と動かない | 電源断・プロセス kill | 最も強い仮定(最も御しやすい) |
| オミッション | メッセージを送り/受け損ねる(が嘘はつかない) | バッファ溢れ・取りこぼし | クラッシュを内包 |
| タイミング | 正しいが時間制約を破る(遅すぎる) | GC停止・過負荷 | 同期系のみ問題化 |
| ビザンチン(任意) | 何でもする:嘘・矛盾・結託 | バグ・侵害・悪意 | すべてを内包(最弱の仮定) |
flowchart LR
C["クラッシュ"] --> O["オミッション"]
O --> T["タイミング"]
T --> B["ビザンチン(任意故障)"]
要するに何か:右に行くほど「敵が強い」。クラッシュは「死んだら黙る正直者」、ビザンチンは「生きたまま矛盾を吐く嘘つき」。
派生の論点 ── フェイルストップと、同期/非同期
- フェイルストップ:クラッシュ+「他ノードが故障を確実に検知できる」理想モデル。実システムでは検知が不確実なので、ここがそのまま 合意問題とFLP不可能性 の難しさに繋がる。
- 同期 / 非同期:メッセージ遅延と処理時間に上限があるか。同期なら「時間内に来なければ死亡」と判定でき故障検出が容易。非同期(上限なし)では「遅い」と「死んだ」が区別できず、FLP不可能性が効く。実システムは部分同期(普段は同期的、たまに崩れる)として扱う。
正しさの観点 ── 何台あれば耐えられるか
故障 f 台に耐える条件は、必要な「重なり(過半数)」から導けます。
クラッシュ耐性(f 台が黙っても、生存ノードの過半数で進む):
ビザンチン耐性(f 台が嘘をついても、正直ノードが多数を確保し矛盾を打ち消す):
直観:ビザンチンでは「黙る」だけでなく「矛盾した嘘を別々のノードに言う」ので、正直派が嘘つきの2倍超いないと真偽を分離できない。だからクォーラム(クォーラム(R+W>N))でも、ビザンチン版は重なりをさらに厚く取ります。
なぜ分散だと難しいか(直観)
単一マシンでは「壊れたら全部止まる(フェイルストップ的)」と思ってよい。分散では一部だけ・嘘も含めて壊れるので、まず敵の強さを宣言しないと議論が始まりません。強い仮定(クラッシュ)で設計を単純化し、本当に必要な所(ブロックチェーン・耐障害金融)だけビザンチンに上げる、が定石です。
⚠️ よくある誤解・落とし穴
- 「ビザンチン耐性にすれば一番安全」→ コスト(N≧3f+1、暗号署名、性能低下)が重い。多くの社内システムはクラッシュ耐性で十分。
- 「クラッシュ故障なら検知は簡単」→ 検知が確実なのは同期かフェイルストップの仮定下だけ。実ネットは非同期寄りで誤検知が起きる。
- 「タイミング故障は故障じゃない」→ GCの長時間停止は「生きてるのに死んだ扱い」を生み、スプリットブレインの温床。
- 「ビザンチン=悪意」だけ→ メモリ化け・ビット反転・設定ミスも任意故障として現れる。
対応ラボ
なし(概念回)。N≧2f+1 の「過半数の重なり」は クォーラム(R+W>N) のラボで定量的に確認します。
関連
- なぜ非同期だと合意が難しいかは 合意問題とFLP不可能性
- 重なりの定量化が クォーラム(R+W>N)
- 前提の取り違えカタログが 分散コンピューティングの誤謬(8つの誤謬)