3.3

View in English

3.3 分散システム

概要と動機

分散システムとは、構成要素が複数のマシンで動き、ネットワークを介して調整するシステムのことです。ネットワークを越えてプロセスの境界をまたぐ瞬間、単一のプロセスの内側にはまったく存在しない、いくつかの厳しい真実を引き継ぎます。ネットワークは信頼できず、そのレイテンシは変動します。メッセージは失われ、重複し、遅れ、順序が入れ替わりえます。リモートのコンポーネントは独自に失敗します。共有の時計はありません。古典的な「分散コンピューティングの落とし穴」(ネットワークは信頼できる、レイテンシはゼロ、帯域幅は無限、トポロジーは決して変わらない)は、障害を引き起こすまさにその仮定を名指ししています。あなたの仕事は、インシデントの間にそれらを再発見するのではなく、最初からこれらの現実のために設計することです。

大きな組織にとって、分散は任意ではありません。国や世界の規模にサービスを提供し、複数の部門をつなぎ、高い可用性を必要とするシステムは、多くのマシン、データセンター、しばしばリージョンにまたがります。企業は、分散トランザクションのシステム、イベントのパイプライン、マルチリージョンのデプロイを運用します。政府は、各機関が自らのシステムを所有し、誰も全体を管理しない、機関間の統合を運用します。ここでは、頑健な設計と脆い設計の差が、見出しになる障害、逃された給付の支払い、規制上の結果として現れます。本章の技法(一貫性の推論、冪等性、バックオフ付きのリトライ、サーキットブレーカー、サガ、分散オブザーバビリティ)が、標準的な防御です。

分散システムの最も難しい部分は、失敗が部分的で断続的であることです。単一マシンのプログラムは、動くかクラッシュするかです。分散システムは、半分動いている状態になりえます。一部のリクエストは成功し、一部はタイムアウトし、一部は静かに失われる、すべてが同時に。本章は、大きなチームが、部分的な失敗のもとで穏やかに劣化し、理解可能なままであるシステムを築けるようにする、推論とパターンに焦点を当てます。

主要原則

  • ネットワークは信頼できない。 すべてのリモートのやり取りを、遅くなり、失敗し、重複し、順序が入れ替わりうるものとして設計します。
  • 分断の間、完全な一貫性と完全な可用性は両立できない。 やり取りごとに意図して選び(CAP/PACELC)、分断がないときでもレイテンシはコストだと覚えておきます。
  • 操作を冪等にする。 安全にリトライできる操作なら、分散の失敗処理のほとんどが扱いやすくなります。
  • すべてのリモート呼び出しにタイムアウトが必要である。 際限のない待ちは、一つの遅い依存先をシステム全体の障害に変えます。
  • ビジネスが許す所では結果整合性を好むが、明示的にする。 ユーザーと監査人は、古いデータを見るかもしれないときを理解していなければなりません。
  • 失敗を隔離する。 バルクヘッドとサーキットブレーカーが、一つの失敗するコンポーネントがすべてに連鎖するのを止めます。
  • 見えないものはデバッグできない。 分散フローには、すべての跳躍にわたる、相関したトレーシング、メトリクス、ログが必要です。
  • 「ちょうど一度の配信」は神話であり、ちょうど一度の処理はエンジニアリングの達成である。 重複排除を伴う少なくとも一度の配信を前提に設計します。

推奨事項

CAPとPACELCで一貫性を推論する

CAP定理は、ネットワークの分断の間、システムは一貫性(すべての読み取りが最新の書き込みを見る)と可用性(すべてのリクエストが応答を得る)のどちらかを選ばなければならないと言います。PACELCは、二つ目の取引を加えます。Else(分断がないとき)でも、Latency(レイテンシ)とConsistency(一貫性)を天秤にかけます。これをシステム全体のラベルとして貼ってはいけません。操作ごとに決めます。銀行の残高の振り替えは強い一貫性を必要とし、二重支払いのリスクを冒すより拒否します。ソーシャルフィードや商品の閲覧カウンターは、可用性と速度と引き換えに古さを受け入れられます。システムが実際には提供しない保証を誰も想定しないよう、各データフローがどの一貫性モデル(強い、因果、自分の書き込みの読み取り、結果整合)を使うかを書き留めます。

冪等性、タイムアウト、リトライ、バックオフを一緒に構築する

これら四つの技法を一つのパッケージとして扱います。すべてのリモート操作にタイムアウトを与え、ハングした依存先がスレッドを永遠にブロックできないようにします。失敗したらリトライしますが、繰り返しても安全な操作に対してだけです。繰り返しても安全とは冪等であることを意味します。各リクエストに一意のキーを割り当て、受信側が重複排除することで、リトライされた「カードに課金する」が二重に課金しないようにします。リトライの間隔を指数バックオフとジッターで空け、同期したリトライの嵐が、短い瞬断を自ら招いたサービス拒否に変えるのを避けます。リトライの回数と合計時間の予算に上限を設けます。永遠にリトライすることは、失敗を動かすだけだからです。冪等性がなければ、リトライは危険です。バックオフがなければ、リトライは破壊的です。

連鎖を止めるために、サーキットブレーカーとバルクヘッドを加える

サーキットブレーカーは、依存先への呼び出しを監視し、失敗が閾値を超えたら「開き」ます。苦しんでいるサービスにさらにリクエストを積み上げる代わりに、クールダウンの期間は即座に失敗し、それから「半開き」にして回復を試します。これは、遅い下流のサービスが、システム全体が止まるまで、すべての呼び出し元のスレッドを使い果たす連鎖を止めます。バルクヘッドは、リソース(スレッドプール、コネクションプール)を分割し、一つの依存先の飽和が、他が必要とする容量を食べられないようにします。どちらも穏やかな縮退と組み合わせます。必須でない依存先が利用できないとき、リクエスト全体を失敗させる代わりに、キャッシュされたかデフォルトの応答を返します。

分散トランザクションを、二相コミットではなくサガで管理する

通常、複数のサービスやデータベースにまたがる単一のACID(原子性、一貫性、分離性、耐久性)トランザクションを保持することはできません。分散二相コミットは遅く、リソースをロックし、可用性を削ります。代わりにサガパターンを使います。ビジネストランザクションを、ローカルトランザクションの連なりとしてモデル化し、それぞれが次を引き起こすイベントを発行し、後のステップが失敗したら、各ステップに、それを取り消す補償的な行動を持たせます。サガには二つの流儀があります。コレオグラフィは、サービスが互いのイベントに反応し、中央のコントローラがありません。オーケストレーションは、中央のコーディネーターがステップを駆動し、推論と監視が容易になります。サガは結果整合性を受け入れます。システムは中間の状態を通って、それから収束します。だから、「進行中」と「補償済み」の状態を考慮するよう、ユーザー体験と監査証跡を設計してください。

ちょうど一度を、少なくとも一度に重複排除を加えたものとして扱う

メッセージブローカーは、失敗をまたいで、ちょうど一度の配信を本当に保証することはできません。ブローカーとあなたが達成できるのは、冪等な処理を伴う少なくとも一度の配信で、それがちょうど一度の効果を生みます。冪等性キーや処理済みメッセージのログを使って、消費者が重複したメッセージを安全に扱えるよう設計します。ブローカーの順序と配信の保証を正確に知ってください。ストリーミングでは、コンシューマーグループ、パーティション、オフセット管理を意図して使い、再処理を安全にして、バグ修正の後にストリームを再生しても、下流の状態を壊さないようにします。

分散フローを端から端まで計装する

サービスの境界をまたいで相関された、オブザーバビリティの三つの柱を採用します。トレース/相関IDをすべての跳躍に伝播させ、単一のユーザーリクエストが触れるすべてのサービスにわたって追跡できるようにします(分散トレーシング)。構造化されたメトリクス(レイテンシのパーセンタイル、エラー率、飽和、スループット)を、サービスごと、依存先ごとに出します。相関IDを運ぶ構造化されたログを出します。これらを使って、サービスレベル目標を設定し、個々のマシンの健全性だけでなく、エラー率やレイテンシのような、ユーザーが実際に感じる症状にアラートを出します。分散システムでは、オブザーバビリティは任意のツールではありません。部分的な失敗のもとでの振る舞いを理解する唯一の方法です。

トレードオフ: 長所と短所

技法長所短所 / コスト
強い一貫性単純な頭の中のモデル。古い読み取りがない分断中の可用性が低い。レイテンシが高い。調整のコスト
結果整合性高い可用性、低いレイテンシ、スケーラブル古い読み取り。複雑な推論。衝突解決が必要
バックオフ付きのリトライ一時的な失敗を自動的に乗り切る誤用すると負荷を増幅する。冪等性と上限が必要
サーキットブレーカー / バルクヘッド連鎖する失敗を防ぐ。速く失敗する複雑さの追加。閾値の調整。早すぎる作動のリスク
サガ(対 二相コミット)スケーラブル、可用、分散ロックなし結果整合性。補償のロジック。推論が難しい

最上位のトレードオフは、調整と独立性の間にあります。マシンをまたいで欲しいあらゆる保証(一貫性、順序、ちょうど一度)は、レイテンシ、可用性、複雑さのコストがかかります。マシンが合意することを要し、信頼できないネットワーク上の合意は高価だからです。スキルは、ビジネスが本当に必要とする保証だけを、操作ごとに買い、それ以外のすべてを穏やかな縮退のために設計することです。一貫性を買いすぎれば、システムは遅く脆くなります。買い足りなければ、数か月後に監査の失敗として表面化する、静かなデータ破損が生じます。

チームで議論すべき問い

  1. レジリエンスのパターンは共有のプラットフォームの既定として提供されていますか。それとも、すべてのチームがタイムアウトとリトライを再発明していますか。 本章は、冪等性、タイムアウト、上限付きのリトライ、サーキットブレーカー、トレーシングを、共有のライブラリとプラットフォームの既定に一度組み込んだときに、最も安く最も信頼できるものとして扱います。大きな組織では、各チームに手作りさせることは、不一致を保証します。冪等でない操作をリトライする経路、タイムアウトのない経路、相関IDを出さない経路。サービスのサンプルを監査して、いくつがすべてのリモート呼び出しに明示的なタイムアウトを設定し、トレースIDを端から端まで伝播しているかを数えて、証拠を持ち込んでください。その数が低いなら、修正は研修のメモではなく、プラットフォームへの投資です。標準の既定はまた、レジリエンスをテスト可能で監査可能にし、金融や政府の規制当局が、示すことをますます期待するものです。

  2. タイムアウトとリトライの予算は呼び出しの連鎖全体にわたって合成されていますか。それとも、深いリクエストが自らをリトライして障害に陥っていますか。 単一のリクエストはしばしば多くの跳躍をまたぎ、各層が独立して自分のタイムアウトで三回リトライすると、最も内側の失敗が掛け算され、外側の呼び出し元は人間が耐えられる限度をはるかに超えて待ちます。ユーザー向けのリクエストに合計の時間予算を設定して連鎖の下へ分割し、内側のサービスが残り時間がどれだけ少ないかを知り、嵐にリトライするのではなく速く失敗するようにします。依存関係グラフと本物のトレースを持ち込み、最悪の場合のタイムアウトとリトライの組み合わせを合計して、ユーザーが実際に待つ時間と比べてください。ジッター付きの指数バックオフと合計の試行回数の上限は、短い瞬断が自ら招いたサービス拒否になるのを防ぎます。深くおしゃべりな同期の連鎖がここでの敵なので、答えは非同期のフローか、より少ない跳躍へと押しやるかもしれません。

  3. 設計が生き延びると主張する失敗を、最後に注入したのはいつで、予期していなかった何が壊れましたか。 レジリエンスのパターンは、システムを意図して失敗させるまで仮説です。インスタンスを殺す、依存先にレイテンシを加える、メッセージの一部を落とす、バッチを二度再配信する。分散システムで興味深い失敗は部分的で断続的なので、コードでは正しく見えるサーキットブレーカーやサガの補償も、完了したかもしれないタイムアウトという本物の状況のもとで誤動作しえます。設計文書ではなく、実際のゲームデーや障害注入の実行の結果を持ち込み、どのアラートが発火したか、トレーシングが障害を特定するのにどれだけかかったか、リトライの嵐が生じたかを記録してください。規制された分野では、失敗をテストした証拠は、監査人に運用上のレジリエンスを示す一部です。一度も実行したことがないなら、最初の実験は、影響範囲を絞り、中止のスイッチを備えたテスト環境に属します。

  4. 各主要なデータフローについて、所有するチームがそれが提供する一貫性モデルを名指しでき、その選択はビジネスが実際に必要とするものに合っていますか。 CAPとPACELCは操作ごとに意図した選択を強いますが、大きな組織では既定はずれです。低リスクのカウンターのために結果整合として始まったフローが、今や支払いを承認したりアクセスを許可したりするものに再利用され、誰も保証を見直しません。相反する考慮は本物です。強い一貫性は分断中の可用性と、分断がないときでもレイテンシのコストがかかり、結果整合性は、古い読み取りと設計しなければならない衝突解決と引き換えに速度を買います。上位のデータフローのカタログを、それぞれ現在のモデル(強い、因果、自分の書き込みの読み取り、結果整合)と、古い、あるいは失われた読み取りのビジネス上の結果をラベル付けして持ち込み、保証が賭け金の正当化する以上に強い、あるいは弱い、不一致を探してください。企業の金融や政府の給付・本人確認のシステムでは、権威ある決定の背後にある結果整合の読み取りは、数か月後に監査の指摘や不当な拒否として表面化する、静かな欠陥の種類なので、そのレビュー自体が、監査人が見せるよう求める証拠です。

  5. 複数サービスにまたがるビジネストランザクションは途中でどう振る舞い、それらを元に戻す補償の責任は誰にありますか。 二相コミットをサガに置き換えることは、システムが目に見える中間の状態を通ることを意味し、あるステップが成功しても、後のステップが失敗してそれを逆転する補償的な行動を引き起こしえます。大きなチームにとって、これは難しいオーナーシップの問いを提起します。承認・借方・貸方・元帳の連鎖は、しばしば複数のチームにまたがり、あるチームが実装し忘れた補償は、お金やレコードを恒久的に不整合のままにします。サービスが中央のコントローラなしに互いのイベントに反応し、フローが見えにくいコレオグラフィと、コーディネーターがステップを駆動し監視するが、運用するコンポーネントというコストのかかるオーケストレーションを比べてください。最も重要なサガの状態図、補償的な行動とその所有者のリスト、「進行中」と「補償済み」の状態がユーザー体験と監査証跡の両方で扱われている証拠を持ち込んでください。銀行や公共部門のケース管理では、規制当局は、途中で失敗したトランザクションに何が起きたかを正確に再構成することを期待するので、モデル化されていない中間の状態は、単なるバグではなく、コンプライアンスのギャップです。

  6. メッセージの消費者は、重複して順序が入れ替わった配信を生き延びますか。そして、ブローカーが問いを強いる前に、それを証明できますか。 ちょうど一度の配信は神話なので、実際の保証は少なくとも一度で、各メッセージが一度、順序どおりに届くと想定する消費者は、フェイルオーバーの後にブローカーがバッチを再配信した日に二重処理します。多くのチームにわたって、リスクは増幅します。共有のストリーム上の冪等でない消費者一つが、他のチームが依存する下流の状態を壊しえて、その失敗は、再生や分断がイベントの順序を入れ替えるまで見えないからです。トレードオフは、冪等性キー、処理済みメッセージのログ、明示的なオフセットとパーティションの処理というエンジニアリングのコストと、静かな破損のコストの間にあります。重要なストリーム上の消費者のリストを持ち込み、どれが重複排除し、どれが単に願っているかを記録し、「大丈夫なはず」という保証ではなく、実際の再配信や再生のテストの結果を持ち込んでください。機関間の政府のデータ交換や企業のイベントパイプラインでは、バグ修正の後に、重複したケースや課金を作らずにストリームを安全に再生できることは、運用上の必要性であり、監査人が示すよう求めるものです。

セクター別の視点

スタートアップ。 動く部品が二、三で、プラットフォームチームもないので、人員を配置できない分散の仕掛けを築くのは控えてください。決済やメッセージングのプロバイダーがすでに提供するSDKにレジリエンスが宿る所では買い、乏しい注意を、不可逆な害を防ぐ二つのパターンに使います。お金を動かす、あるいはアカウントを変更するすべての呼び出しの冪等性キーと、不安定な接続が二重に行動しないよう上限付きのリトライを伴うタイムアウト。ネットワークの跳躍の数を小さく保ってください。加えるすべての同期的な依存先は、気づくオンコールの誰かがいる前に失敗しうるものがもう一つ増えるということだからです。

小規模事業者。 おそらく分散システムの専門家はおらず予算も厳しいので、これを作るのではなく買う問いとして扱ってください。運用しなければならないインフラよりも、リトライ、順序、重複排除を代わりに扱ってくれるマネージドなキュー、マネージドデータベース、プラットフォームを好みます。リスクを平易な言葉で枠づけます。二度実行されたり古いデータを返したりしたら顧客を傷つける操作を把握し、ベンダーがすでに提供する冪等性と少なくとも一度の機能をオンにします。トランザクションを偽るために共有データベースを通じてサービスをつなぐのは避けてください。それは、管理する道具のないまま、最も難しい分散の問題を静かに再現するからです。

大企業。 中核の問題は多数のチームにわたる一貫性なので、冪等性、タイムアウト、上限付きのリトライ、サーキットブレーカー、相関されたトレーシングを、各グループに手作りさせず、共有のプラットフォームの既定として提供します。フローごとの一貫性モデルと配信保証の宣言の仕方を標準化し、障害注入とゲームデーを定期的な周期で実施し、一つのサービスがプラットフォームを障害にリトライできないよう、合計の時間予算が深い呼び出しの連鎖にわたって合成されるようにします。レジリエンスを、ユーザーに見える症状に対するサービスレベル目標を伴う、測定される能力として管理します。あなたの規模では、タイムアウトの欠落一つが、見出しになる障害に連鎖しうるからです。

政府。 機関間のシステムは、誰も全体を所有しないことを意味するので、管理できない境界のために設計します。少なくとも一度の配信を伴う持続的なキュー、安定したメッセージIDでの重複排除、監査人に端から端までの跡を与えるために機関の線をまたいで流れる相関ID。調達と透明性の規則は、各統合の一貫性モデルと配信保証を文書化し、権威ある決定(本人確認、適格性、給付)をキャッシュされたエンドポイントではなく、強く一貫した読み取りに保つよう促します。テストされた失敗の証拠と再構成可能なトランザクション履歴を成果物として扱ってください。運用上のレジリエンスと公衆への説明責任は、内部の気の利いたものではなく、契約上かつ法定の義務だからです。

事例

スタートアップ。 小さなフィンテックのスタートアップは、ネットワークで話す動く部品が二つしかありません。アプリとサードパーティの決済プロバイダー。この規模でも、すべての課金リクエストに冪等性キーを持たせ、バックオフ付きのリトライで呼び出しを包むので、不安定な接続での応答の脱落が、顧客に二重に課金することは決してありません。これを飛ばすのは初日には安く感じられますが、本物のユーザーに当たった最初の重複した課金は、サポートの火事、返金、若い会社が負えない信頼の傷のコストがかかります。

大企業。 世界的なライドシェアのプラットフォームが、サガを通じて乗車の支払いを処理します。カードの承認、乗客への課金、運転手への入金、元帳の記入で、それぞれが補償的な取り消しを伴うローカルトランザクションです。すべてのステップが冪等性キーを持つので、ネットワークのタイムアウト後のリトライが二重に課金することはありません。不正スコアリングのサービスへの呼び出しは、サーキットブレーカーの背後にあります。ピーク時にそれが劣化すると、ブレーカーが開き、すべての乗車をブロックする代わりに、乗車は保守的なスコアにフォールバックします。顧客が乗車に異議を唱えたとき、分散トレーシングにより、エンジニアは十数個のサービスをまたいでそれを数秒でたどれます。

政府。 国の本人確認サービスは、多くの機関が確認のために使います。権威ある状態チェックのための強く一貫した読み取り(古い本人データに対して給付を承認してはならない)と、大量で重要でない検索のための結果整合のキャッシュされたエンドポイントを提供します。機関間のデータ交換は、少なくとも一度の配信を伴う持続的なメッセージキュー上で行われ、各機関の消費者はメッセージIDで重複排除するので、再配信されたレコードが重複したケースを作りません。相関IDが機関の境界をまたいで流れ、市民のデータが部門間をどう動いたかの端から端までの跡を監査人に与えます。

ビジネスケース: 動機、ROI、TCO

分散システムの規律は安く買え、その不在は破局的に支払われます。採用のコストは、冪等性、タイムアウト、リトライ、サーキットブレーカー、トレーシングを共有のライブラリとプラットフォームの既定に組み込むエンジニアリングの時間です。それは、すべてのチームの利益になる、ささやかで大半が一度きりの投資です。それを採用しないコストは、大きな障害で測られます。プラットフォーム全体の障害に連鎖するタイムアウトの欠落一つ、何千もの顧客に二重に課金する冪等でない決済の経路、永続的に不整合なままデータを残すサガのない分散トランザクション。それぞれが、直接の収益、是正、評判のコスト、規制された分野では罰金を伴う、見出しになるインシデントです。

リーダーシップには、可用性と影響範囲を軸に論拠を示してください。レジリエンスのパターンは、深刻なインシデントの頻度と長さの両方を直接減らし、それらは経営陣がすでに稼働時間と平均復旧時間として追跡している指標です。分散オブザーバビリティはMTTRへの単一の最大のてこです。相関されたトレーシングを持つチームは、サービス間のインシデントを何分の一かの時間で解決します。これらの能力は共有のプラットフォームの既定として提供するのが最良なので、チームごとの限界コストは低く、組織全体の見返りは複利で増えます。TCOの議論は単純です。最初からレジリエンスを組み込むことは、問題を強いる障害の後に後付けするコストの何分の一かです。

アンチパターンと落とし穴

  • タイムアウトがない。 一つのハングした依存先が、すべてのスレッドを使い果たし、システム全体を落とします。
  • 冪等でない操作のリトライ。 重複した副作用。二重の課金、重複したレコード、二倍のメール。
  • リトライの嵐。 バックオフとジッターのない同期したリトライが、小さな瞬断を障害に増幅します。
  • ちょうど一度の配信を想定する。 ブローカーがいずれ配信する重複メッセージで壊れる消費者を作ること。
  • 共有データベースを通じた分散トランザクション。 ACIDを偽るために一つのデータベースを通じてサービスを結合し、分散モノリスを再び作ること。
  • 部分的な失敗の無視。 リモート呼び出しが完全に成功するか完全に失敗するかを想定し、「タイムアウトしたがおそらく完了した」の処理がないコード。
  • 相関IDがない。 十台のマシンの無関係なログをgrepして、サービス間のインシデントをデバッグすること。
  • おしゃべりな同期の呼び出しの連鎖。 どれか一つの遅い跳躍がリクエスト全体を止める、深い同期の依存グラフ。

成熟度モデル

  • レベル1: 開始。 リモート呼び出しがローカルの呼び出しのように扱われます。タイムアウトは欠けているか素朴で、リトライはないか無謀で、失敗はシステム全体に連鎖します。一貫性や配信についての共有された見方はなく、サービス間のインシデントのデバッグは、事後にマシンごとのログを探り回ることを意味します。
  • レベル2: 発展。 一部のチームはタイムアウトと基本的なリトライと少しの冪等性を加えますが、実践はサービスごとに一貫しません。ログは集約されていますが相関されておらず、跳躍をまたぐリクエストの追跡は手作業です。分散トランザクションはモデル化されるのではなく、動くことが願われ、一貫性の保証は個々のエンジニアの頭の中にあります。
  • レベル3: 標準化。 冪等性、上限付きのリトライ、ジッター付きのバックオフ、サーキットブレーカー、バルクヘッドが、共有ライブラリを通じて組織全体の標準です。補償的な行動を伴うサガが複数サービスのトランザクションを扱い、相関IDを伴う分散トレーシングが整っており、すべての主要なデータフローが一貫性モデルと配信保証を文書化しています。ルールは書き留められ、各チームに任されるのではなく組織全体で徹底されます。
  • レベル4: 管理。 レジリエンスは、存在するだけでなく、ベースラインに対して測定されます。サービスごと、依存先ごとに、エラー率、レイテンシのパーセンタイル、飽和、スループットを追跡し、リトライ比とサーキットブレーカーの開放率を観察し、ユーザーに見える症状にサービスレベル目標を設定します。合計の時間予算が呼び出しの連鎖にわたって合成されることが検証され、サービス間のインシデントの平均復旧時間は監視される指標で、障害注入とゲームデーの結果が、各変更をゲートする数字に反映されます。
  • レベル5: オーケストレーション。 レジリエンスは、継続的に改善される、組織全体に統合された、状況に適応するプラットフォームの既定です。障害注入は影響範囲を絞って本番で日常的に実行され、システムは設計により穏やかに劣化し、一貫性と配信の選択は、負荷とビジネスの賭け金の変化に応じて見直されます。レベル4の指標が自動的な対応と着実なアーキテクチャの進化を駆動するので、分散した資産は、単に生き延びるのではなく、インシデントごとにより頑健になります。

議論のためのアイデア

  1. 重要な操作のうち、今日本当に冪等なものはどれで、静かにそうでないのはどれですか。
  2. 各主要なデータフローについて、チームは一貫性モデルと配信保証を記憶から述べられますか。
  3. 直近の連鎖的な障害を、サーキットブレーカーはどこで防いだはずですか。
  4. 現在、失敗する単一のリクエストを、それが触れるすべてのサービスをまたいでたどるのに、どれくらいかかりますか。
  5. あなたの「分散トランザクション」のうち、運に頼っているのはどれで、補償を伴う本物のサガはどれですか。
  6. メッセージブローカーが一時間、すべてのメッセージを二度再配信したら、何が壊れますか。

要点

  • ネットワークは信頼できず、失敗は部分的だと想定します。すべてのリモートのやり取りを、遅さ、損失、重複、順序の入れ替えのために設計します。
  • CAP/PACELCを用いて、操作ごとに一貫性と可用性を決めます。各フローが提供するモデルを文書化します。
  • 冪等性、タイムアウト、上限付きのリトライ、ジッター付きのバックオフは一つのパッケージです。他の三つなしにリトライを採用してはいけません。
  • サーキットブレーカーとバルクヘッドが失敗を封じ込め、補償を伴うサガが、機能しない分散トランザクションを置き換えます。
  • 配信を少なくとも一度として扱い、ちょうど一度の効果を達成するために処理を冪等にします。
  • 相関されたトレーシング、メトリクス、ログは、分散フローを理解し運用する唯一の方法です。

参考文献とさらなる読み物

  • Martin Kleppmann, Designing Data-Intensive Applications
  • Andrew Tanenbaum and Maarten van Steen, Distributed Systems: Principles and Paradigms
  • Michael Nygard, Release It!: Design and Deploy Production-Ready Software
  • Sam Newman, Building Microservices
  • Chris Richardson, Microservices Patterns (sagas, transactional messaging)
  • Eric Brewer, “CAP Twelve Years Later” and Daniel Abadi on PACELC
  • Leslie Lamport, “Time, Clocks, and the Ordering of Events in a Distributed System”
  • Cindy Sridharan, Distributed Systems Observability
  • Nassim Nicholas Taleb’s notion of antifragility (as applied by resilience-engineering literature)