DDIA 第8章:分散システムの難しさ(要約)
Tony Duong
4月 14, 2026 ・ 1 分
概要
第8章は、分散システムがなぜ難しいかを説明する。障害は二値ではなく曖昧に現れることが多い。単一ノードのプログラムならクラッシュは明確だが、分散システムではネットワーク遅延、パケット損失、retry、ノード過負荷、クロックドリフトが、呼び出し側から似た症状に見える。
章の中心メッセージは、信頼性は理想状態を前提にするのではなく、不確実性を前提にした設計から生まれるということ。
中核となる障害パターン
部分障害
分散システムでは、一部コンポーネントだけが失敗し、他は稼働を続ける。1つの要求があるサービスでは成功し、別のサービスでは失敗することで、全体ワークフローが中間の不確実な状態に残る。
信頼できないネットワーク
ネットワークは非決定的で、メッセージは遅延・損失・重複・順序入れ替わりが起こりうる。したがって、request/response のタイミングだけを真実とみなせない。
timeout の曖昧さ
timeout は 失敗の証明ではない。次の可能性がある:
- 実行前に失敗した
- 実行は成功したが応答が遅れた
- 実行も応答送信も成功したが応答が失われた
この曖昧さが分散システム設計の中心課題になる。
信頼できない時計
wall clock はドリフトやジャンプが起こり、NTP補正も入る。timestamp を厳密順序保証として使うと、特にリージョン間・ノード間で微妙なバグを生みやすい。
実践的な設計パターン
idempotency
同じ要求を繰り返しても追加副作用が出ない操作にする。これで結果が不確実なときも retry を安全にできる。
timeout / retry / backoff
意図的に設計する:
- timeout が短すぎる -> 偽障害が増える
- timeout が長すぎる -> レイテンシ悪化とリソース拘束
- backoff なし retry -> retry storm
backoff(多くは jitter 付き指数)で同時負荷ピークを抑えられる。
永続的な状態遷移
ワークフローの状態遷移を durable storage/log に記録する。結果が曖昧なとき、明示的な状態機械は復旧を助け、重複処理を防ぐ。
防御的なサービス境界
すべてのサービス間呼び出しを「遅い/落ちる可能性あり」として扱う。circuit breaker、graceful degradation、非クリティカル機能向け fallback を持つ。
正しさと協調
複数ノードが値やリーダーに合意する必要があると、ネットワーク不確実性により協調は高コストかつ壊れやすい。多くのシステムは要件に応じて整合性・可用性・レイテンシをトレードオフする。
実務的には、可能ならグローバル協調を避け、必要なときはクリティカルな不変条件を明示的に管理することが重要。
アプリケーションエンジニアへの示唆
- 最初から idempotent API を設計する
- ワークフローを暗黙の happy path 連鎖ではなく明示的な状態としてモデル化する
- retry 率・timeout 率・重複リクエスト率を主要メトリクスとして計測する
- 分散ロジック実装前に時刻/順序前提を文書化する
要点
- 分散システムの障害は曖昧に起こるため、"失敗したか" だけでは不十分
- timeout は真実ではなく曖昧さの境界を示す
- 正しさはネットワークと時間に関する前提の置き方に依存する
- 信頼性は防御的パターン(idempotency、backoff付きretry、observability、明示的状態)で作る
🌐 Claudeによる翻訳