👏

【データ指向アプリケーション要】第8章 分散システムの問題

2025/01/03に公開

「データ指向アプリケーションデザイン」の第8章では、分散システムが抱える問題がたくさん紹介されてる。
ここでは、その中でも特に大事な3つのトピック、

  1. フォールトと部分障害
  2. 信頼性の低いネットワーク
  3. 信頼性の低いクロック

について、要点を押さえながらまとめていく。

1. フォールトと部分障害

全体が壊れるんじゃなくて、一部だけ壊れるかも

  • 分散システムだと、複数のマシンサーバーがネットワークでつながっているわけだけど、
    その中の一部のマシンが壊れるとか、一部だけ通信が不調になることがよくある
  • これを「部分障害」って呼ぶのだが、システム全体がダウンするほどじゃなくても、
    あるノード(サーバー)だけが動いてないとか、ディスクが壊れてるとか、そんな状況も想定しないといけない

単なるマシン障害だけじゃない

  • ソフトウェアバグとか、過負荷とか、えぐいネットワーク遅延とか、障害の原因はいろいろ
  • 分散システムは「障害が起きる前提」で設計・運用しないと、箇所が壊れただけで全体がアウト、なんてことになりかねない

対策のイメージ

  • レプリケーションでデータを複数のノードにコピーしておいて、一部が壊れても他のノードで対応する
  • タイムアウトとリトライをしっかり設計して、応答が無いノードは一時的に切り離す
  • 結局、「一部がダメになってもシステム全体は動く」構造を作るのが肝心

2. 信頼性の低いネットワーク

ネットワークは万能じゃない

  • 「LANとかインターネットで繋がってるから常に通信OK」って思いがちやけど、実際はパケットがロストしたり遅延が起きたり一時的に切断されたりと信頼性が低い
  • 特に、複数のデータセンター間をまたぐような地理的に離れた分散システムだと、ネットワークの遅延や障害はもっと起きやすい

「通信が遅いのか、相手が死んでるのか?」

  • 分散システムの難しさで有名なのが、タイムアウトの問題
    • 「相手から返事が無い…これは単に遅いだけ? それとも相手が落ちた?」
    • 確定的に「死んだ」と判断するのは難しくて、一定時間待って応答がなければ「死んでるかもしれない」とみなすしかない
  • それを間違うと、元気に動いてるノードを「落ちた」と誤判定して排除してしまったり、本当に落ちてるのにいつまでも待ち続けたりする

対策のイメージ

  • 再送(リトライ): パケットロストに備えて同じリクエストをもう一度送る。
  • 分断耐性: ネットワークが分断されても、オフラインで動ける仕組みや、後で再同期する仕組みを用意する
  • フェイル検出: タイムアウトを設定して、一定時間応答がなければ「怪しい」と判断し、切り替え処理(フェイルオーバー)をする

3. 信頼性の低いクロック

分散環境での時計ズレ

  • マシンが5台、10台、100台…って増えてくると、それぞれのマシンで時間(クロック)が微妙にズレてる可能性があるんだ。
    • 例えば、サーバーAが「1月1日 12:00」と思ってる時に、サーバーBは「1月1日 12:00:05」(5秒進んでる)みたいなズレがある可能性が存在する
  • さらに、NTPサーバー(ネットワーク経由で時計合わせする仕組み)の状態によって変わるし、そもそもネットワークが不安定だと同期も途切れたりする

タイムスタンプがあてにならない

  • 分散システムで複数のイベントが起きた時、「どっちが先?」「これは同時?」「後?」ってタイムスタンプ比較で判断するのは危ない
  • 「先に起きたはず」のイベントがあとになって記録されてしまうとか、同時なのに片方が1秒先みたいな記録になるとか、意外とある

対策のイメージ

  • 論理クロックやバージョン管理:
    • 物理的な時刻に頼らずに、イベントの因果関係から順序を把握するやり方がある
    • たとえば「この更新はあの更新の後だ」って記録するために、「バージョン番号」や「ベクトル時計」みたいな仕組みを使う
  • 分散トランザクションを組むときに、できるだけ「物理時刻に依存しない」設計をする
  • どうしても時刻が必要な場合は、リーダーのノードの時刻を正とするなど、1箇所に寄せる工夫をすることもある

まとめ

  1. フォールトと部分障害

    • 分散環境じゃ、一部だけ壊れるのは当たり前。全部止まらないような設計が重要。
  2. 信頼性の低いネットワーク

    • パケットロス・遅延・切断が当たり前。
    • 「ノードが落ちたのか、ただ遅いだけか」の判定も悩ましい。
  3. 信頼性の低いクロック

    • マシン同士の時計はズレる。物理時刻だけを頼りにすると混乱しやすい。
    • イベントの順序をどう管理するかが鍵。

分散システムは便利なぶん、「障害が普通に起きる世界」で動かすイメージを持たないといけない。
ネットワークも時計もあまり頼れないから、エラーや遅延を前提にした冗長化や再送、バージョン管理などなどを考える必要がある。
確かにこの章を読むまでは大体のことは安定してるんだからそこまで冗長化とかしまくって悲観的にならんでもええんとちゃうかなと思っていたけど、読んだ後では「まじで5,6章大事!これがないと堅牢なシステムとはいえない。」って思うようになった。

Discussion