📓

第8章:信頼性は“崩れる前提”で考えるもの──完璧を捨てる技術

に公開

第8章:信頼性は“崩れる前提”で考えるもの──完璧を捨てる技術

『データ指向アプリケーションデザイン(DDIA)』第8章を読んだメモです
崩れない設計より「崩れても壊れない設計」へ
信頼性をどう設計するか、自分の経験と照らして読み解きました

🔙 目次に戻る


多くのシステムは「壊れないことを前提」に作られている

でも現実はこう:

  • コンピューターは物理。壊れるしズレる
  • 人間は“常に10%間違える処理”なんて信じたくない

だから「壊れるときは盛大に壊れる設計」になりがち
壊れる前提に立つ設計とは、人間の“壊れなさ信仰”と戦うことでもある


信頼性とは「弱い入力」をどう扱うか

TCPが信頼性を担保するのは、「信頼できないネットワークをどう補完するか」に全振りしているから

アプリケーション側でも同じ
ユーザー入力という“信用ならない外部入力”を:

  • バリデーションして
  • リトライ促して
  • それでもダメなら破棄 or フォールバック

という設計にする必要がある
信頼性を作るとは、“信用できない世界”と折り合う設計のこと


ネットワークは「気まぐれで、物理的で、嘘をつく」

  • 地球の気候にも影響される
  • 光速すらボトルネックになる
  • VMの壁を越えるたびにレイテンシが積まれる
  • ZoomやゲームでラグるのもUDPの性質ゆえ

つまり、ネットワークは「がんばってるけど信用ならん奴」


タイムアウトと指数バックオフは基本中の基本

でもそれが万能かというと…?

  • クラウドが死んでたらリトライ先がそもそもない
  • エラー画面の設計がなければ“失敗”で終わる
  • 死活監視してても「確実には死んだ」と言えない

部分的な故障を“なんとなく生きてる”ように見せる仕組みが必要


「時刻」は絶対じゃない、“目安”にすぎない

  • タイムスタンプは不確実
  • スノーフレークIDもズレることがある
  • Spanner の TrueTime は「信頼できる幅」を定義して commit している

つまり:

正しい時刻がわからないなら、正しい範囲を作ればいい

という柔らかい整合性の哲学


真実はひとつ…ではなく、“だいたいひとつ”

分散システムでは「多数決による故障判定」が基本:

  • 本当に死んでるかどうかは誰にもわからない
  • 「たぶん死んでるっぽい」を集めて判断するしかない

これがクラッシュ検出と信頼性の“実際”


ビザンチン障害と、信頼性の限界点

  • 嘘をつくノード
  • 外部スパイ
  • 意図的な混乱

こうなると、公開鍵や署名での検証くらいしか対抗策がない
“正しく動くように見える嘘つき”がいたら手に負えない
ここに対抗するには「限界を知って割り切る設計」が重要


部分同期モデルこそが現実

完全同期・非同期はあくまで理論モデル
現実のシステムは:

  • 一部のコンポーネントが同期
  • 他は非同期に動き
  • それでも整合性がとれるように補正を入れる

という“ちぐはぐで合理的”な世界で動いている
その調整設計こそがエンジニアリング


設計とは「壊れ方を選ぶ」行為

完全性の保証には、必ず何かの犠牲がある:

  • GCによる停止
  • リアルタイム処理による可読性・スループットの低下
  • 並列性の代償としての整合性の崩壊リスク

どこまで壊れていいのか?何を守るのか?
それを決めるのが設計

図8: 信頼性ループ ── 失敗から学び、次の失敗を小さくするサイクル


✍️ まとめ:信頼性は“抽象のスコープ設定”で生まれる

設計とは抽象のスコープをどう絞るか

  • DDDもOOPもアルゴリズムも、現実を一部だけ扱う技術
  • 複雑さを削るための道具であって、万能ではない

だから信頼性も「どこまで信じて、どこからは諦めるか」で決まる
完璧な正解を追いかける行為ではなく、制約の中で“知的折り合い”をつける作業なのだ


💡 設計Tips

  • ネットワークや入力は信用しない前提で設計する
  • タイムアウトとフォールバックは必須(リトライだけで戦わない)
  • 時刻は「範囲」で扱う思想が必要
  • 故障判定は“だいたいの多数決”でしかできない
  • 信頼性は“壊れるものとどう付き合うか”で決まる

🔙 目次に戻る

Discussion