01 / 読書ガイド
読書ガイド
引用
Vitillo, R. (2022). Understanding Distributed Systems: What Every Developer Should Know About Large Distributed Applications (2nd ed.). Roberto Vitillo.
章の要約
第2版(バージョン2.0.0、2022年3月)は約330ページで、序論、五つの部(通信、協調、スケーラビリティ、レジリエンス、保守性)、短い結びの章からなる全34章で構成される。序文によれば、第1版を全面的に書き直したものである。各章はコンパクトで数ページのものも多く、さらに深く知りたい読者のために論文、RFC、技術記事を脚注で示している。演習問題はない。
第1章:序論
分散システムを、メッセージを交換して協力するノードの集まりとして定義し、それが構築される理由(本質的に分散している用途、可用性、1台のマシンに収まらない負荷、レイテンシ)を説明したうえで、各部の名前にもなっている五つの課題を予告する。二人の将軍問題を使って協調がなぜ難しいかを示し、スループット、応答時間、スケールアップとスケールアウト、「ナイン」で表す可用性を導入する。最後の節では、ビジネスロジック、インターフェース、アダプタの観点からサービスの構造(ポートとアダプタのアーキテクチャ)を説明する。
第I部 第2〜5章:信頼できるリンク、安全なリンク、ディスカバリ、API
第I部は、分散アプリケーションが依存するネットワークスタックを積み上げていく。第2章は、TCPがIPの上に信頼できる通信路をどのように作るかを説明する。セグメントと確認応答、接続のライフサイクルと3ウェイハンドシェイク、フロー制御、輻輳制御、独自プロトコルを扱う。第3章は、TLSがTCPの上に暗号化、認証、完全性、ハンドシェイクを加える仕組みを示す。第4章はDNSを、分散的・階層的で結果整合性をもつキーバリューストアとして紹介し、読者は初めて結果整合性に出会う。第5章はRESTfulなHTTP APIを、リソース、リクエストメソッド、ステータスコード、OpenAPI、APIの進化、冪等性の順に説明する。
第II部 第6〜13章:システムモデル、障害検出、時間、リーダー選出、レプリケーション、協調の回避、トランザクション、非同期トランザクション
著者はこの部を、最も理論的で最も難しい部分だと述べている。まずプロセス、リンク、タイミングに関するシステムモデルを導入し、続いて障害検出を扱う。第8章は物理クロック、論理クロック、ベクトルクロックを、第9章はRaftのリーダー選出とその実務上の考慮点を扱う。第10章はステートマシン・レプリケーション、合意、一貫性モデル(CAP定理とPACELC定理のトレードオフを含む)、チェーン・レプリケーションを取り上げる。第11章は協調を避けるより弱いモデル、すなわちブロードキャストプロトコル、CRDT(衝突のない複製データ型)、Dynamo型データストア、CALM定理、因果一貫性に進む。第12章と第13章は、パーティションやサービスにまたがるトランザクションを扱う。ACID、分離性、原子性、NewSQLシステム、そして長時間にわたる非同期トランザクションのためのアウトボックスパターンとSagaである。
第III部 第14〜23章:HTTPキャッシュ、コンテンツ配信ネットワーク、パーティショニング、ファイルストレージ、ネットワーク負荷分散、データストレージ、キャッシュ、マイクロサービス、コントロールプレーンとデータプレーン、メッセージング
第III部は、単純なCRUD型ウェブアプリケーションをスケールさせていく過程をたどり、機能分割、パーティショニング、レプリケーションという三つのパターンを軸に内容を組み立てる。クライアント側のHTTPキャッシュとリバースプロキシから始まり、CDN、範囲パーティショニングとハッシュパーティショニング、Blobストレージ(例としてAzure Storageのアーキテクチャを使う)を経て、DNS、トランスポート層、アプリケーション層での負荷分散へと進む。第19章はレプリケーションとパーティショニングによってリレーショナルデータベースをスケールさせ、次にNoSQLストアを紹介する。第20章はキャッシュのポリシーと、ローカルキャッシュと外部キャッシュの違いを論じる。最後の三章は、マイクロサービスとAPIゲートウェイ、コントロールプレーンとデータプレーンの分離(制御理論に関する短い節を含む)、そして配信保証、exactly-once処理、障害、バックログを含む非同期メッセージングを扱う。
第IV部 第24〜28章:よくある障害原因、冗長性、障害の分離、下流へのレジリエンス、上流へのレジリエンス
第IV部は、よくある障害原因の一覧から始まる。ハードウェア障害、誤ったエラー処理、設定変更、単一障害点、ネットワーク障害、リソースリーク、負荷の圧力、連鎖障害であり、リスク管理の節もある。続いて、冗長性は障害が相関していない場合にしか役立たない理由、シャッフルシャーディングとセルラーアーキテクチャによる障害の分離、そして障害を起こした依存先に耐えるためのパターン(タイムアウト、リトライ、サーキットブレーカー)と、過負荷からサービスを守るためのパターン(ロードシェディング、負荷平準化、レート制限、一定量の処理)を説明する。
第V部 第29〜33章:テスト、継続的デリバリーとデプロイ、モニタリング、オブザーバビリティ、管理性
最後の部は、本番環境でのシステム運用を扱う。第29章はテストの範囲と規模を論じ、形式検証を簡単に紹介する。第30章は、変更がレビュー、ビルド、本番前環境、本番環境を経て、ロールバックに至るまでをたどる。第31章はメトリクス、サービスレベル指標(SLI)と目標(SLO)、アラート、ダッシュボード、オンコール対応を扱い、第32章はログとトレースを通じてオブザーバビリティを説明し、第33章はコードではなく設定によってシステムの振る舞いを変える方法を扱う。
第34章:結びの言葉
短い結びの章。
主要概念
第1〜5章:序論と通信
- 漏れのある抽象化:本書がTCP、TLS、DNSを教える理由。ネットワークライブラリは、問題が起きるまで下位層を隠している。
- 冪等性:リクエストを再試行しても二重に適用されないようにAPI操作を設計すること。
- 結果整合性:レプリカが一時的に食い違っても最終的には収束するという性質。DNSを通じて最初に登場する。
第6〜13章:協調
- システムモデル:アルゴリズムについて推論するための、プロセス障害、リンクの信頼性、タイミングに関する前提の集まり。
- 論理クロックとベクトルクロック:同期した物理クロックに頼らずにイベントの順序を決める方法。
- 合意とステートマシン・レプリケーション:レプリカに同じ操作列について合意させ続けること。Raftを例に説明される。
- Saga:分散ロックの代わりに、補償処理を伴うローカルなステップを連ねて構成する長時間のトランザクション。
第14〜23章:スケーラビリティ
- パーティショニング:データをキーの範囲やハッシュで分割し、ノードに分散できるようにすること。
- コントロールプレーンとデータプレーン:設定やメタデータの管理と、リクエストの処理とを分離すること。
- exactly-once処理:メッセージングシステムがメッセージ配信について保証できることとできないこと。
第24〜33章:レジリエンスと保守性
- 相関した障害:共通の原因をもつ障害で、単純な冗長化では防げない。
- サーキットブレーカー:障害を起こした依存先への呼び出しを止め、障害の連鎖を防ぐ仕組み。
- サービスレベル目標(SLO):許容される振る舞いを定める、サービスレベル指標の目標値。
批判的分析
長所
- 理論と実践の中間を埋める。 序文は、この分野の資料の多くが学術的な端か実務的な端のどちらかに偏っていると説明し、本書は意図的に両者を組み合わせている。そのため、Raft、CRDT、CALM定理が、CDN、ロードバランサー、オンコールの実践と並んで登場する。本書のサイトで引用されているゲルゲイ・オロスは、深い理論書と面接対策本との間の空白を埋める本だと評している。
- 本番運用の経験に基づく。 MozillaやMicrosoft(のちにAWS)の大規模データ基盤に携わった著者の経歴は第III〜V部に表れており、古典的な教科書が扱わない話題、すなわちレート制限、シャッフルシャーディング、セルラーアーキテクチャ、デプロイパイプライン、SLO、オブザーバビリティを取り上げている。
- 短く、つながっている。 分野全体を約330ページで扱い、各部の冒頭に章の概観があり、後の章が前の章に立ち返る(たとえばTCPのフロー制御からサービスレベルのレート制限へ)。著者のサイトにある無料サンプルには、前付け、完全な目次、冒頭の章が収録されており、購入前に文体を確かめられる。
短所
- 意図的に深さより幅を優先。 序文は、大規模システムの構築経験が豊富な人には物足りないかもしれないと明言している。数ページしかない章も多く、アルゴリズムは証明ではなく文章と図で説明される。
- 演習やプロジェクトがない。 演習問題がないため、授業では独自の課題を用意する必要がある。
- クラウドとバックエンドに焦点。 構造を説明する節は、本書が主にビジネスサービスを実装するバックエンドアプリケーションを対象とすると述べている。目次には並列計算やピアツーピアシステムの章はなく、いくつかの例は特定のクラウドサービスから取られている。
コースにおける位置づけ
このコースの文献リストの中で、ヴィティッロの本書は最も短く、最も実践的な入口である。ファン・スティーンとタネンバウムの Distributed Systems と、クールリスらの Distributed Systems: Concepts and Design は、アーキテクチャ、通信、命名、協調、一貫性、レプリケーション、障害耐性、セキュリティをはるかに深く扱う、原理を重視した本格的な教科書である。本書は概観として先に読むことも、原理がクラウドサービスの中でどう現れるかを見るためにどちらかと並行して読むこともできる。クレップマンの Designing Data-Intensive Applications はデータシステム(ストレージエンジン、レプリケーション、パーティショニング、ストリーム処理)をさらに深く掘り下げており、第II部と第III部の後に進む自然な次の一冊である。
カシャン、ゲラウイ、ロドリゲスの Introduction to Reliable and Secure Distributed Programming は、本書が第II部で非形式的に説明するシステムモデル、ブロードキャスト、合意といった抽象を厳密に扱う本である。パチェコとマレンセクの An Introduction to Parallel Programming は、マルチコアプロセッサ、クラスタ、GPU向けの並列プログラムを書くという、本書が扱わないコースの別の側面をカバーしている。
本書の使い方
本書は、ウェブやモバイルアプリケーションのバックエンドに携わる、あるいはこれから携わろうとする開発者を対象としている。プログラミング経験とウェブアプリケーションの仕組みについての一般的な知識が必要で、理論の素養は前提とされていない。
- 概観のための通読: 第1章と各部の導入を読めば、半日ほどで分野の見取り図が得られる。
- 分散システムの授業での中核: 第II部(第6〜13章)はゆっくり読むべき部分である。原理を扱う教科書の対応する章と組み合わせ、脚注に挙げられた論文(たとえばRaftやCRDTに関するもの)で理解を深めるとよい。
- 実務者にとっての中核: 第III部と第IV部。スケーラビリティの章は一つのアプリケーションを段階的に組み立てていくので、順番に読むとよい。
- 初読では省略可: TCP、TLS、HTTPにすでに詳しければ第I部。第V部は本番サービスに取り組むときに後から読んでもよい。
演習がないため、アイデアを小さく実装してみると役立つ。たとえばベクトルクロック、指数バックオフとジッターを用いたリトライ方針、単純なハッシュベースのパーティショナーなどである。電子版はときどき更新され、バージョン番号が付いている。著者のサイトでは無料サンプルが提供されている。
