DDIA 読書ノート 【第8章】
分散システムにおける困難
分散システム特有の困難としては二つ、不確定性と部分障害がある。そしてこれらが発生する理由としても二つ、ネットワークの不確かさとクロックの不確かさを起因としている。
これらを解決するのは非常に困難、あるいは経済性とのトレードオフ上諦めざるを得ないかのどちらかで、特殊な機能要件が求められる環境、例えば金融や航空宇宙システムなどを除いて基本的にはこれらが存在するものとして扱わなければならない。
不確かなネットワーク
ネットワークがいかに信頼性に欠けるものであるか、という点は普段異常系の設計をする際にお馴染みかと思う。 ここで知っておく必要があるのは
- フォールトを検知する唯一確実な方法はタイムアウトしかない、ということ
- そしてそのタイムアウトをどのように決めるかの絶対的な方法は存在しない、ということ
の二つである。
どこでフォールトが起こっているかを調べる方法をいくつか例に挙げており、どれも有効な手段ではあるが、究極的にはアプリケーションからの応答がないと処理が実行されたかどうか・成功したかどうかの判定はできないため、確実な方法としてはタイムアウトを待つ、という選択肢だけが残る。
そしてタイムアウトが発生する原因として処理の遅延や輻輳、キューイングの詰まりなどがあるが、いずれの場合も遅延がどのくらいになるかという上限は保証されておらず、レスポンスタイムの分布をもとに経験則的に設定する以外に方法はない。
このようにネットワークに関する性質はとにかく都合の悪い要素が多いのだ。そしてそれはクロックの話題にも当てはまる。
不確かなクロック
クロックには時刻を計測するものとある時点からの増加分を数えていく二つの方法があり、単調増加のクロックの方が正確な時刻との同期を取る必要がない分信頼性が高いと言えるが、とはいえ正確に時刻を刻んでいく保証はない。
クロックに依存したくなる典型的な例としてイベントの順序づけがある。
ローカルなクロックに依存してしまうと悲惨で、あるノードは他のノードに対して未来にいるためいろんな悪いことが起こり得る。
これを解決するために、イベントの相対的な発生順序だけを意味する、論理クロックというものを導入できるが、この論理クロックを生成するコンポーネントがボトルネックになりがちである。
クロックが信頼できないもう一つの話題としてプロセスの停止について述べている。ガベージコレクションが典型例だ。
車のエアバッグなど、プロセスの停止が致命的な事故につながる可能性のある環境ではプロセスの停止を予測可能なものにする仕組みがあることにはあるが、これもまたトレードオフの話で、OS から何から全てのソフトウェアで一貫してサポートされている必要があるため、その利用は組み込みなどの環境に限られる。
この困難にどう立ち向かうのか
章の最後にはこの困難に立ち向かう方法としてサイエンスな視点、つまりある点を仮定し、その仮定のもとである性質を満たし続けるアルゴリズムを導入する、という考え方を紹介する。
章の冒頭に述べているように、その仮定が成り立たなくなる事象というのはいつか発生する、発生するものとして捉えないといけないのだが、その境界線を認識することで、具体的にどういうケースでその性質が満たされず、そしてどのように対応するのかということを事前に決めておける、非常に有用な考え方だ。
最後に、プログラミングとは全く関係のない感想だが、分散システムと人と人とのコミュニケーションは非常に似ているなと感じた。
相手が何を考えているかを把握する絶対的な手段は存在せず、コミュニケーションに頼らざるを得ない一方で、コミュニケーションはとても不確実性だ。
こうした不確かさを抱えつつも、全体としてはなんとか協調していく必要がある、というのは分散的なものの宿命なのかもしれない。
References
- システム障害なしにうるう秒を乗り切る技術の発達について
- クロックに依存する危険性と leap smearing について触れたエッセイ。読み物として面白い。
- 最近よく聞く Quorum は過半数(多数決)よりも一般的でパワフルな概念だった
- Quoram とは何かについて解説した記事。単純に多数決と言えない奥深さを知れる。
- Predictable low
latency
- Java システムの GC のレイテンシに対応するため、ノードを primary-secondary 構成にして、先にレスポンスを返した方の結果を採用する仕組み。どれだけ効果があるのかは不明だが、興味深い。