← 記事

システムの信頼性

再試行が停止になった場合

すべてのレイヤーが独自に回復しようとすると、わずかな速度の低下がシステム全体の障害になる可能性があります。連鎖と、それを阻止できる境界線をたどってください。

MGCA group · 発行済み

制御された狭い処理レーンと待機中のリクエストが大量に蓄積された等尺性のサービス ランドスケープ。
アーキテクチャの概念図: より多くの作業を許可しても、処理能力は増加しません。
失敗の連鎖をたどる
  1. 1. わずかな遅れが第二の人生を獲得する
  2. 2. 掛け算はチーム間で発生します
  3. 3. 待合室は収容力を生みません
  4. 4. 過負荷が借用できない境界を構築する
  5. 5. バックオフはタイミングを変更します。ジッターが会社を変える
  6. 6. 復旧トラフィックには帰宅ルートが必要
  7. 7. 進行中の仕事を探す
  8. 8. 挑戦をやめることを許されるシステム

1 つの意図、27 の可能な試み

フルサイズのビジュアルを開く ↗
1 つの意図、27 の可能な試み最悪の場合の分岐例: 3 つのレイヤーで、それぞれがオリジナルを含めて合計 3 回の試行を許可します。早期の成功またはキャンセルはありません。実際のトラフィックは実装によって異なります。リングエリアはワークロードの尺度ではありません。1
本来の動作
3
最初の再試行レイヤー各層で合計 3 回の試行
9
2 番目の再試行層試み
27
最も深い依存関係試み
再試行の所有権と総許容量を明示的にします。例示的なモデル — 測定された生産データではありません
最悪の場合の分岐例: 3 つのレイヤーで、それぞれがオリジナルを含めて合計 3 回の試行を許可します。早期の成功またはキャンセルはありません。実際のトラフィックは実装によって異なります。リングエリアはワークロードの尺度ではありません。
説明と仮定

最悪の場合の分岐例: 3 つのレイヤーで、それぞれがオリジナルを含めて合計 3 回の試行を許可します。早期の成功またはキャンセルはありません。実際のトラフィックは実装によって異なります。リングエリアはワークロードの尺度ではありません。

最初に失敗したリクエストは、多くの場合、停止の中で最も興味のない部分です。依存関係に予想より時間がかかり、呼び出し側の 1 人が待機を諦め、アプリケーションが再試行します。それは賢明な回復措置のように見えます。この困難は、他の呼び出し元が何千人も同じ結論に達し、いくつかのレイヤーが独自の試みを行い、元の作業がまだ実行されている場合に現れます。現在、システムは、回復メカニズムによって生じた負荷からの回復に、その容量の占める割合が増大しています。個々の再試行ループの中に、明らかに不合理に見えるものがない限り、動作の組み合わせが破壊的になります。

明示的に仮説的な注文状況サービスを考えてみましょう。通常、受信する作業に対して十分な容量がありますが、ダウンストリームの依存関係により 2 分間速度が低下します。リクエストはより長く滞留し、呼び出し側のタイムアウトが切れ始め、クライアント ライブラリが別の試行を開始します。外部サービスにも再試行ポリシーがあります。ユーザー インターフェイスには、独自の期限が過ぎたため、再試行ボタンが表示されます。ビジネスの需要はほとんど変化していませんが、依存関係では、完了できる作業が少なくても、より多くの作業が試みられます。この記事では、その連鎖をたどり、デザインがそれを中断する可能性がある場所を検討します。このシナリオとすべての数値例は説明のためのものであり、MGCA の顧客インシデントや測定されたベンチマークを説明するものではありません。

再試行は、古い意図を表している場合でも、リソースに対する新しい要求です。この区別が失敗を理解するための出発点になります。企業は依然として 1 つのステータス更新、1 つの提出された申請書、または 1 つの完了したレポートを必要とする場合があります。インフラストラクチャは、それを生成するための複数の試行を処理している可能性があります。ダッシュボードがリクエストを基礎となる操作に関連付けずにカウントすると、追加のアクティビティが顧客の需要の急増のように見える可能性があります。成功が有用な結果ごとではなく、試行ごとに測定される場合、サービスは、サービスを待っている人のエクスペリエンスよりも健全に見える可能性もあります。

1. わずかな遅れが第二の人生を獲得する

タイムアウトは、この呼び出し元はどれくらい待つのかというローカルな質問に答えます。それ自体では、リモート操作が停止したか、実行前に失敗したか、または確認応答を送信せずに完了したかについては答えられません。それらは異なる結果です。読み取りの場合、リクエストを繰り返すと主にリソースが消費される可能性があります。書き込みの場合、不確実な結果によって正確性の問題が発生する可能性もあります。受信側システムがすでに変更をコミットしている可能性があります。呼び出し側が明確な応答を受け取りたいと望んでも、別の実行が安全になるわけではありません。したがって、再試行をトランスポート層に割り当ててアプリケーションの残りの部分が影響を受けないと仮定するのではなく、容量の保護とビジネスの正確性を一緒に考慮する必要があります。

速度低下に対する最初の対応は、多くの場合、タイムアウトを増やすことです。これにより、通常の変化が停止と誤解される誤った障害を減らすことができます。また、より多くのリクエストがリソースを長時間占有し続ける可能性もあります。タイムアウトを短くすると、逆のトレードオフが生じます。呼び出し元は待機状態をより早く解除しますが、以前の作業がアクティブなままである間に置換試行を開始する可能性があります。どちらの方向も本質的には正しいわけではありません。有益な質問は、どのリソースが占有されたままなのか、どの作業が実際に停止するのか、そして選択した期限がタスクを完了する価値とどのように関係するのかということです。これらの質問に答えずに数値を変更すると、圧力が除去されるのではなく、むしろ変化する可能性があります。

時計も複数あります。接続の確立、名前の解決、ID トークンの取得、プールされた接続の待機、および応答の受信は、それぞれ呼び出し側の使用可能な時間の一部を消費する可能性があります。初期の待機を除外したリクエスト タイムアウトは、操作全体について誤解を招く印象を与える可能性があります。逆に、すべての段階で個別に寛大な許容量を設定すると、ユーザー側の約束をはるかに超える全体的な遅延が発生する可能性があります。設計には、リモート呼び出しが開始される前と試行の間に費やされた時間を含む、経過時間の一貫した説明が必要です。重要な境界はタスク全体であり、設定が最も簡単なタイマーではありません。

仮想サービスでは、内部クライアントが 20 秒間継続できる一方で、表示されているページは 5 秒後に待機を停止すると想像してください。これらの値は推奨設定ではありません。それらは所有権の問題を明らかにします。その期間の一部では、サービスは、元の読者がすでに離れているリクエストを処理している可能性があります。ページが新しい操作を送信すると、古い作業と新しい作業が競合します。キャンセルが伝播された場合でも、受信側コンポーネントは、何を安全にキャンセルできるかを定義する必要があります。ネットワーク待機の停止と、コミットされたトランザクションの取り消しは、同じ機能ではありません。期限を設定すると、結果の効果を元に戻すことなく、結果の有用性が終了する可能性があります。

したがって、最初の中断ポイントは、所有者がいる期限になります。コンポーネントは、操作の残り時間がどのくらいかかるか、その操作内で別の試行が妥当に完了するかどうか、その時間が使い果たされたときに何が起こるかを知っている必要があります。答えは、明らかな失敗、ステータス参照を伴う非同期操作の保持、または不完全としてマークされた結果である可能性があります。同じ作業を別の無制限の再試行ループに目に見えない転送にすることはできません。リカバリ ポリシーは、タスクの実際の制約内で有効な結果が得られる可能性を高める場合に役立ちます。

Amazon のエンジニアリング ガイダンスでは、タイムアウト、バックオフ、ジッター、およびタイムアウトした呼び出しによってすでに副作用が生じているリスクについて説明しています。 Microsoft は、関連する再試行ストームのアンチパターンについて説明しています。試行を頻繁に行うと、障害が発生しているサービスの回復が妨げられる可能性があります。これらの情報源は、この記事の特定の数値を検証するのではなく、広範なメカニズムをサポートしています。以下の設計推論では、そのメカニズムを意図的に簡素化したサービスに適用して、結果を検査可能な状態に保ちます。 [1] [2]

2. 掛け算はチーム間で発生します

3 回の試みは控えめに聞こえます。それぞれが合計 3 回の試行を許可する 3 つのレイヤーは、まったく異なる場合があります。すべての外側の試行がすべての内側の試行を引き起こし、初期にはどれも成功しないという特定の最悪の場合の仮定の下では、最も深い依存関係は 1 つの元の操作に対して 27 回の試行を受ける可能性があります。これは呼び出し階層全体での乗算であり、すべての失敗が自動的にそのカウントを生成すると主張するものではありません。キャンセル、期限、早期の成功、回線の状態、および再試行の実際の所有権によって、この値が減少する可能性があります。計算のポイントは、各コンポーネントを個別に検討する場合に見落としやすい相互作用を明らかにすることです。

ここでは用語が重要です。 3 回の再試行として説明されている設定は、元の試行にさらに 3 回の試行を加えたものを意味する場合がありますが、3 回の再試行には元の試行が含まれます。これらの定義を混同すると、実装の詳細が入力される前に計算が変更されます。アーキテクチャの議論では、各境界で許可される試行の合計を書き留め、どのコンポーネントがそれらを開始するかを特定する必要があります。また、クライアント ライブラリ、ゲートウェイ、インフラストラクチャによって提供される動作も含める必要があります。アプリケーション コードのみを示す図では、トラフィックを支配する再試行メカニズムを省略できます。呼び出し元から障害を隠すコンポーネントも、依然としてシステムのワークロードに影響を及ぼします。

組織的な原因は理解できます。各チームは、独自のサービスが短時間の中断を許容できることを望んでいます。共有ライブラリは標準ポリシーを採用します。ゲートウェイは別の保護層を追加します。ワーカーは例外を、メッセージを放棄して再度受信する理由として扱います。これらの選択はいずれも不注意である必要はありません。この失敗は、ポリシーが予算を共有せずに依存関係を共有しているために発生します。ローカルの回復力は集団的な楽観主義になっています。すべての参加者は、別の試行が手頃な価格であると想定していますが、事業運営によって生成される試行の総数については参加者は責任を負いません。

冒頭の放射状の図を見るとそれが分かります。そのリングは 1 つの元の操作を表し、その後、意図的に制限されたモデルでの 3 回、9 回、および 27 回の可能なダウンストリーム試行を表します。リングは測定されたトラフィックではなく、そのエリアはパフォーマンスの推定値ではありません。これらは、別の長方形のアプリケーション ランドスケープを描画せずに、分岐の仮定を検査する方法です。一つの意図を外に向かって導き、新しい作品がどこで生まれるのかを問う。複数のレイヤーが独立して拡張できる場合、最後のクライアントの最大再試行のみを確認しても、ルート全体が課すことができる最大負荷は確立されません。

実際的な対応策の 1 つは、アプリケーションが操作を判断するのに十分なコンテキストを持っている境界で、再試行の所有権を明示することです。これは、すべてのシステムがすべての復元ロジックを 1 か所に集中化する必要があるという意味ではありません。アプリケーションがより長いタスクを管理している間に、トランスポートは切断された接続を合理的に回復する可能性があります。要件は、それらの組み合わせた動作が理解され、制限されることです。上位層がタスクの許容量を使い果たしたと判断した後、下位層は完全なビジネス アクションを黙って再開すべきではありません。再接続、再送信、再実行の間の境界は、設計と観察の両方で見える必要があります。

再試行バジェットにより、リクエストごとの最大値を超える 2 番目の制限が追加されます。アプリケーションは、障害時に発生する追加作業の総量を制限できます。会計単位は、リクエスト、同時試行、経過時間、加重コスト、またはその組み合わせなど、慎重に選択する必要があります。安価なキャッシュ読み取りと高価なレポートは、必ずしも交換可能なトークンであるとは限りません。このメカニズムでは、予算が空の場合に何が起こるかを定義する必要もあります。拒否された再試行をプライベート キューに移動するだけで、元のリミッターからプレッシャーを隠しながらプレッシャーを維持できます。有用な予算により、制約されたリソースに到達する動作が変わります。

そのような予算が正しいと判断する普遍的な割合はありません。利用可能な回復容量、依存関係コントラクト、タスクの値、および失敗の動作は異なります。サービスは、永続的な障害中に高価な作業を増大させることを拒否しながら、短い一時的なエラーに対して狭い許容範囲を予約する場合があります。また、適格なタスクを個別に制御されるバックグラウンド プロセスに延期する場合もあります。重要なのは、システムに負荷がかかっている場合、成功がほとんどない場合、および複数の呼び出し元が一緒に失敗した場合でも、ポリシーが意味を持ち続けることです。補充が成功に依存する予算では、偶発的なロックアウトや無制限の緊急オーバーライドではなく、その低成功期間の明確な解釈が必要です。

失敗した試みは新しい業務指示ではありません

書き込み可能なサービスの場合、操作の ID は試行後に存続する必要があります。クライアントが同じインテントを再送信するたびに新しいビジネス識別子を生成する場合、受信側は合理的にリクエストを異なる操作として扱うことができます。関連するコンテンツをチェックせずに識別子を再利用すると、実質的に異なる変更に同じキーが付加される可能性があります。したがって、冪等性の設計には、リクエスト ID という名前のフィールド以上のものが必要です。スコープ、意図したアクションとの関係、保持期間、および互換性のないコンテンツとともに繰り返される識別子が到着した場合の定義された応答が必要です。

結果の記録も同様に重要です。受信側が完了した操作を識別できても、その結果を回復できない場合、重複実行が防止されていても、呼び出し側は不確実なままになる可能性があります。サービスは、以前の結果を返すことができるか、ステータス参照を提供できるか、または調査が必要かを判断する必要があります。正しい配置は、操作とその情報処理要件によって異なります。一般的な区別は安定しています。古い命令の認識、別の影響の防止、既存の影響の説明は関連する機能ですが、これらは同じメカニズムによって自動的に提供されるわけではありません。

3. 待合室は収容力を生みません

キューを使用すると、ワークロードの制御が容易になります。これにより、受諾と実行が分離され、消費者に持続可能な速度で作業を処理する機会が与えられます。また、サービスが果たせない約束が増大していることが隠蔽される可能性もあります。したがって、キューの深さは、それ自体では成功の指標でも説明でもありません。 10 個の遅いレポートを含むキューは、1,000 個の小さな更新を含むキューよりも多くの作業を表す可能性があります。緊急リクエストの短いキューはすでに古すぎる可能性があります。有益な観察は、バックログをサービスコスト、完了能力、および結果がビジネス価値を失うまでの時間を結び付けます。

Microsoft のキューベースの負荷平準化パターンでは、バッファを使用して需要を平滑化することについて説明し、ダウンストリーム処理を制御する必要性を強調しています。サービスに仕事が提供されるとパターンが変わります。スループットは生成されません。この境界は、仮想的な減速に適用する場合に重要です。消費者が容量が戻るたびにできるだけ早くキューを排出するだけであれば、元のサージを再現することができます。コンシューマーの自動スケーリングによって、制約されたままの依存関係に対する圧力が高まると、キューは過負荷を解決するのではなく、移動させてしまいます。バッファから解放される量には、独自の動作制限が必要です。 [3]

バックログが増大し続けてもキャパシティは回復可能

フルサイズのビジュアルを開く ↗
バックログが増大し続けてもキャパシティは回復可能同一の作業単位で有効期限のない計算された流体モデル。余分な試行トラフィックは、その影響を分離するために一定に保たれます。これらは予測やパフォーマンスの測定ではありません。02,4004,8007,2009,60012,000060120180240300360
オリジナル作品のみ: 80 ユニット/秒
追加試行あり: 120 ユニット/秒
減速が始まってからの時間 (秒)
120秒で容量が回復オリジナルのみのバックログは 240 秒でクリアされます
キューに入れられたワークユニット
同一の作業単位で有効期限のない計算された流体モデル。余分な試行トラフィックは、その影響を分離するために一定に保たれます。これらは予測やパフォーマンスの測定ではありません。
説明と仮定

能力: 120 秒間 60 ユニット/秒、その後 100 ユニット/秒。初期バックログ: ゼロ。感度の場合の追加試行: 40 ユニット/秒。

計算データを見る ↗

チャートでは意図的に単純な流体モデルを使用しています。本来の需要は 1 秒あたり 80 単位の作業です。処理能力は最初の 120 秒間で 60 に低下し、その後 100 に戻ります。各ユニットの想定コストは同じです。初期のバックログはゼロであり、ストレージはこの計算に制限効果を持たず、期限切れになったり永久に失敗したりする作業はありません。これらの仮定により、演算が透明になります。これらは、実際のブローカー、データベース、ネットワーク、またはアプリケーションの完全な動作を説明するものではありません。目的は、増幅された試行ワークロードが遅れ続ける一方で、変化のないビジネス ワークロードがどのように回復できるかを示すことです。

このモデル化されたキューに追加の試行トラフィックが許可されない場合、速度低下中に毎秒 20 ユニットが蓄積されます。 2 分後のバックログは 2,400 になります。新しい需要が 80 のままで容量が 100 に戻ると、サービスには 1 秒あたり 20 ユニットの予備処理容量が確保されます。したがって、バックログのクリアにはさらに 2 分かかります。開始から 240 秒の時点でキューは空になります。回復は、キャパシティが戻った瞬間には行われません。サービスはまず、到着よりも遅い間に受け入れた作業を返済する必要があります。

ここで、表示された間隔全体で 1 秒あたり 40 単位の試行回数を想定して追加します。これは感度の問題であり、特定の再試行アルゴリズムを予測するものではありません。減速中は到着数が 120 対 60 になるため、2 分の時点までに 7,200 ユニットが蓄積されます。定員が 100 人に戻った後も、到着者数は依然として完了数を 20 人上回っています。 6 分時点で、バックログは枯渇するどころか 12,000 に達しています。この比較における追加需要は、その影響を分離するために一定に保たれています。実際の再試行数は、期限、バックオフ、正常な完了、およびアプリケーションが適用する制御によって変化します。

2 つのトレースは同じルールに基づいて計算されます。つまり、バックログはマイナスになることはできず、承認された作業から完了した作業を差し引いた値で変化します。結果の違いは、すべての再試行が有害であることを証明するものではありません。短い独立した失敗の後に適切に選択された試みにより、貴重なタスクを回復することができます。トレースは、使用可能な容量に対して試行を評価する必要がある理由を示します。制約されたサービスが追加の負荷を処理できない場合、永続性を高めると、タイムリーな結果を誰も受け取らない期間が長くなる可能性があります。基礎となる依存関係がまだ修復中である場合でも、余分なトラフィックを減らすことが回復アクションになる可能性があります。

提供された負荷と許容された負荷の区別は重要です。リミッターは多数のリクエストを認識しますが、ワーク キューに入るのは一部のみを許可する場合があります。拒否された試行には依然として境界で何らかのコストがかかるため、アドミッション パスは圧力下でも動作するのに十分な低コストである必要があります。単に拒否するかどうかを決定するためだけに、同じコストのかかる依存関係呼び出しを実行すべきではありません。同時に、安価な拒否は顧客のタスクとして完了したわけではありません。サービスは、キューの増加の見かけの減少が正常に実行されたと誤解されないように、需要、許可、拒否、および有用な完了を個別に観察する必要があります。

キューの経過時間により、欠落している時間のディメンションが追加されます。特定のレポートが意思決定会議の前にのみ役立つと仮定します。たとえシステムが最終的に成功を報告したとしても、会議後にそれを処理することにはほとんど価値がない可能性があります。その作業を無期限に続けると、依然として重要な新しいタスクが遅れる可能性があります。ただし、期限切れは、グラフを改善するために作業を黙って削除するのではなく、目に見える結果を伴うビジネス上の決定である必要があります。呼び出し元は、リクエストが完了のために受け入れられたか、拒否されたか、置き換えられたか、または期限切れが許可されたかを知る必要があります。契約を放棄することによって実現された安定したキューは、回復されたサービスではありません。

同じ理由で優先順位も複雑になります。緊急のタスクを優先すると重要な結果は保護されますが、緊急の作業が永続的に続くと他のすべてが枯渇する可能性があります。テナント、操作、およびワークロード クラス間の公平性には、明示的なポリシーが必要です。単一のグローバル先入れ先出しキューは、分離性が低くても操作が簡単な場合があります。多くの小さなキューにより、監視とスケジューリングの複雑さが増す一方で、分離が改善されます。有益な選択は、どの当事者が希少なリソースを共有しているか、また、総需要にすぐに対応できない場合に組織がどの約束を守ることができるかによって決まります。

4. 過負荷が借用できない境界を構築する

4 つの異なる制限、1 つのサービス

フルサイズのビジュアルを開く ↗
4 つの異なる制限、1 つのサービス等角投影の概念図。これらのレイヤーは、物理的な距離、スループット、または規定の Azure 製品トポロジではなく、制御の責任を表します。ジオメトリの縮尺は一定ではありません。04
依存関係その能力を尊重してください。制御された速度で回復作業を開始します。
03
アクティブな実行呼び出し元を待っているだけでなく、実際の実行中の依存関係の作業を制限します。
02
待機中の作業保管期限と耐用年数。ライブ需要とリプレイを分離します。
01
入場料安価に受け入れ、拒否、または延期する。操作のアイデンティティを保持します。
バッファーを大きくしても下位層が高速になるわけではありません。拒否された仕事には明確な結果が必要です。
等角投影の概念図。これらのレイヤーは、物理的な距離、スループット、または規定の Azure 製品トポロジではなく、制御の責任を表します。ジオメトリの縮尺は一定ではありません。
説明と仮定

入場料 — 安価に受け入れ、拒否、または延期する。操作のアイデンティティを保持します。 · 待機中の作業 — 保管期限と耐用年数。ライブ需要とリプレイを分離します。 · アクティブな実行 — 呼び出し元を待っているだけでなく、実際の実行中の依存関係の作業を制限します。 · 依存関係 — その能力を尊重してください。制御された速度で回復作業を開始します。

等角図では、アドミッション、待機、アクティブな実行、ダウンストリームの依存関係という 4 つの問題が 1 つのサービス ボックスに圧縮されることがよくありますが、それらは分離されています。各層には異なる希少資源があります。入学経路は迅速な決定が必要です。バッファには有限のストレージと年齢分布があります。ワーカーはメモリ、接続スロット、実行時間を消費します。依存関係には独自の容量と権限の境界があります。これらのレイヤーを可視化すると、ワーカー数の増加がサービス全体の容量の増加と同等ではない理由を説明できます。ある層の制限は、次の層が無制限の共有プールから借用するときに無効になる可能性があります。

アクティブなジョブの数を適度な数に制限しながら、各ジョブが多数の同時ダウンストリーム呼び出しを開くことを許可するワーカーを考えてみましょう。最上位の制限が責任を負っているように見えますが、重要なリソースはその下で増加しています。基になる操作が実際に依存関係の消費を停止する前に、タイムアウトによってアプリケーション レベルの許可が解放された場合にも、同じ問題が発生します。リミッターはあることをカウントし、リソースは別のことを支払います。設計では、許可を取得する時点、許可が対象とする作業、および許可の解除を正当化する観察を特定する必要があります。

分離は、関連性のない作業が最も遅い依存関係によってその能力のすべてを失わないようにする必要があるため、役立ちます。個別のプールまたは同時実行許可を使用すると、失敗した統合が正常な統合に必要なリソースを占有することを防ぐことができます。これは無料ではありません。別のパーティションが使用中である間、パーティションの容量がアイドル状態のままになる可能性があり、パーティションが多すぎるとシステムの調整が困難になる可能性があります。この値は、より予測可能な障害境界になります。この選択は、関数ごとに個別のキューとスレッド プールを作成する汎用的な命令としてバルクヘッドを提示するのではなく、どのワークロードが相互に影響を与える可能性があるかという観点から説明する必要があります。

サーキット ブレーカーは、再試行ポリシーとは異なる決定を行います。失敗する可能性が十分に高いリソースへの試行を一時的に停止し、制御されたプローブで回復を評価できるようにします。 Microsoft のパターンはその分離を表しています。仮想サービスの場合、興味深い疑問は、ブレーカーの周囲で何が起こるか、つまり、ブロックされた試行が再試行バジェットを消費するかどうか、フォールバック作業で同じ失敗した依存関係が使用されるかどうか、およびプローブの母集団がすべてのインスタンスにわたって制限されたままであるかどうかです。アーキテクチャ図に描かれたブレーカーは、それ自体では周囲の動作を確立しません。 [4]

フォールバックにより、誤って状況が悪化する可能性があります。キャッシュ ミスによってすべてのリクエストが元の依存関係に送信される場合、一見回復力のあるキャッシュ パスでは、ヒット率が低い期間に負荷が集中する可能性があります。代替プロバイダーのクォータが低い場合、すべての発信者を一度に切り替えるとインシデントが転送される可能性があります。劣化した応答の計算にコストがかかる場合、使用できるほど十分な容量が確保されない可能性があります。フォールバックは、独自の依存関係と正確性条件を持つ別のワークロードとして評価される必要があります。その名前は、それがより安価で、より安全であり、障害が発生したプライマリ パスの規模で利用できるという証拠ではありません。

古い情報が受け入れられないタスクもあります。タイムスタンプが表示された古い情報結果を返すことは、一部の読み取り者にとっては妥当な品質低下となる可能性があります。古い承認決定を使用したり、古いビジネス状態を最新のものとして表示したりすると、別のリスクが発生する可能性があります。アプリケーションは、結果のどの部分が劣化する可能性があるか、その状態がどのように伝達されるか、どの操作が拒否されなければならないかを決定する必要があります。不確実性を隠して可用性を維持すると、たとえエラー率ダッシュボードの見栄えが良くなったとしても、ビジネスに損害を与える可能性があります。障害応答には、サービスが知っていることの真実の説明が保存される必要があります。

Google の過負荷の扱いでは、応答の低下と、応答が低下しても対応できない場合に作業を拒否する必要性について説明しています。これは、敗北主義的に聞こえる可能性がある設計の選択に有用なコンテキストを提供します。つまり、一部の要求を拒否することで、他の要求を完了する能力を保護できます。仮想サービスのビジネス優先順位は選択されません。これらの優先順位には、どのタスクが待機する可能性があるか、どのタスクが低下する可能性があるか、どのタスクがすぐに失敗する必要があるかについて、明示的な契約が必要です。技術的なメカニズムは、単に文書に記録するのではなく、その契約を強制する必要があります。 [5]

5. バックオフはタイミングを変更します。ジッターが会社を変える

2 つのクライアントには、個別に意味のある遅延が発生しても、同時に到着する可能性があります。大規模な集団で同時に障害が発生し、すべてのメンバーが同じ間隔で待機した場合、次のウェーブは同期を保つことができます。遅延が大きくなると、必ずしも各波のメンバーを分散させることなく、波間の間隔が変化します。ジッターはタイミングに変動をもたらします。重要な考え方は、式への装飾的な追加としてのランダム性ではありません。それは、単一の調整されたバーストとして繰り返し現れる回復者集団を回避することです。必要な分散と境界は、プロトコル、期限、観察されたワークロードに適合する必要があります。

指数関数的バックオフとジッターに関する AWS の議論は、決定論的な再試行タイミングが作業のクラスターを残す理由を示しています。これはタイミング メカニズムをサポートするものであり、別のサービスの汎用パラメーターの選択ではありません。仮説的なアプリケーションでは、ランダムな遅延が長くなると試行が分散される可能性がありますが、一部の試行は呼び出し側の有効な期限を超えてしまう可能性があります。範囲が短いと期限に適合する可能性がありますが、同期性が低下する可能性が低すぎます。設計には両方の制約が必要です。選択されたアルゴリズム名を、生成されたすべての遅延がタスクに適切であるという証拠として扱うべきではありません。 [6]

再試行ループでは、応答の解釈も必要です。認証の失敗、拒否されたビジネス ルール、および一時的な容量制限は、同じ動作を要求しません。変更されていない無効なリクエストを繰り返しても、通常、リクエストを無効にした情報を修復することはできません。スロットリング応答はタイミングのガイダンスを提供する場合がありますが、呼び出し元は依然として独自の期限と総許容量を尊重する必要があります。接続に失敗すると、実行が不確実になる可能性があります。分類は、すべての例外に別の試行回数を割り当てる単なる検索ではなく、操作に関する決定につながる必要があります。

試行スケジュールには、有益な作業を行う時間、応答を待つ時間、および次の試行までの待機時間を含める必要があります。遅延が個別にリストされている場合、ポリシーは短く見えますが、実行が含まれるとタスク全体の許容時間を超えることがあります。アプリケーションで許可されている場合は、重複した試行も考慮する必要があります。並列投機によりレイテンシが短縮される場合がありますが、そのために追加の容量が消費されます。過負荷下では、そのトレードオフが特に高くつく可能性があります。組織は、サービスがいつその選択を行うのか、どの操作が対象となり、何が余分な作業を停止するのかを把握する必要があります。

スケジュールだけが同期のソースではありません。定期的なポーリング、トークンの更新、スケジュールされたバッチの開始、および共有イベント後に再起動される一連のプロセスはすべて、アクティビティを集中させる可能性があります。したがって、明示的な再試行ループが改善された後でも、仮想的な停止が再発する可能性があります。この有益な調査では、ワークロード全体でどのクロックが共有されているか、またそれらのクロックによってどのような高価なアクションがトリガーされるかを尋ねます。バックグラウンド作業を分散することは役立つかもしれませんが、締め切り、営業時間、外部サービス窓口によってその自由が制限される可能性があります。正しい解決策は、スケジュールされたタスクの目的を維持しながら、関連する到着パターンを変更します。

もう一度ボタンを押した相手

人々は別の再試行層になる可能性があります。リクエストが受け入れられたかどうかを説明せずに回転する画面が再送信を促します。ボタンを無効にすると、偶発的な重複が減る可能性がありますが、応答が失われた後のサーバーの状態を確立できません。永続的な操作参照と明確なステータス ビューにより、リーダーは別のリクエストを作成する代わりに最初のリクエストを検査する方法が得られます。インターフェイスは、受け付けられた操作を待つことと、サーバーに新しい操作を開始するよう要求することを区別する必要があります。この区別は、短い対話型の期限が長い非同期プロセスの前にある場合に特に価値があります。

ソフトウェアは約束をしているので、文言は重要です。結果が不明なときにリクエストが失敗したと言うのは、処理が受け入れられステータスがチェックされていると言うのとは異なるアクションを促すことになります。どちらのメッセージも、システムが持っていない確実性を主張すべきではありません。ステータス ビューは、インシデント中に制御不能なポーリング ソースになることも回避する必要があります。間隔の選択、必要に応じてステータスのキャッシュ、および繰り返しの更新の制限は、同じ容量設計の一部です。有用なユーザー エクスペリエンスは、人々が不安を新たな仕事の波に変えることなく、意図を取り戻すのに役立ちます。

6. 復旧トラフィックには帰宅ルートが必要

キュー駆動サービスでは、処理の成功と確認の成功は別のイベントであるという別の区別が導入されます。ビジネス効果は、ブローカーがメッセージを削除できることを認識する前に完了する可能性があります。確認応答が失われた場合、システムはメッセージを再び見ることができます。 Azure Service Bus では、転送、ロック、決済を配信の別個の部分として文書化します。アーキテクチャ上の結果として、メッセージの処理 ID がビジネス操作に関連付けられ、繰り返しの配信が意図的に処理されます。配信数のしきい値を増やしても、繰り返しの実行が安全であるとは限りません。 [7]

作業者は、繰り返しでは有効にならない作業を認識する必要もあります。不正な形式のペイロード、サポートされていない操作バージョン、または前提条件が永久に欠落している場合は、修正または調査が必要になる場合があります。アクティブ キューに無期限に戻すと、成功の可能性が向上せずに容量を消費する可能性があります。別の障害パスによって通常のワークロードを継続できますが、そのパスには所有者と目に見える結果が必要です。内容がまったく検査されない配信不能キューは回復戦略ではありません。これは、たまたまメインのスループット チャートの外にある、未解決の約束の蓄積です。

Microsoft の Service Bus デッドレターに関するドキュメントでは、セカンダリ サブキューの役割と、アプリケーションがそのメッセージを処理する必要性について説明しています。仮想サービスの重要な選択は、再送信の前に何が起こるかです。チームは、根本的な欠陥が修正されたかどうか、当初のビジネス意図が現在も継続されているかどうか、以前の試みがすでに影響を及ぼしているかどうかを確認する必要があります。これらの質問をスキップする一括再生により、古い不確実性を新たな負荷に変換できます。回復手順では、保存されているすべてのメッセージを再実行しても同様に安全なものとして扱うのではなく、作業を選択できる必要があります。 [8]

容量が回復すると、実際の需要と過去の復旧作業が競合します。すべての古いタスクを最大利用可能速度で排出するサービスは、現在のユーザーに 2 回目の停止を与える可能性があります。新しい作業のためにすべてを予約するサービスでは、バックログが決して解消されない可能性があります。したがって、復旧作業の解放率には、実際の予備容量とビジネスの優先順位に関連付けられたポリシーが必要です。依存関係の動作の変化に応じて調整できます。重要な点は、リカバリはそれ自体がワークロードであり、通常のトラフィックに適用される制限から免除される特別なカテゴリではないということです。

回復判定には停止条件もあります。レイテンシーが上昇した場合、最も古いライブリクエストが有効期間を超えた場合、重複検出で予期しないパターンが見つかった場合、または依存関係が再びスロットリングを開始した場合、リプレイは一時停止する必要がある場合があります。関連するシグナルはサービスによって異なります。重要なことは、古い作品をリリースする人またはメカニズムがそれらを観察し、バッファーが新たな急増の源になる前に行動できることです。フィードバック パスのない再生コマンドは永続性を提供しますが、その結果をほとんど制御できません。

出所を保存すると、フィードバックがより有用になります。操作は、最初の送信、その後の試行、キュー配信、および手動修正全体にわたって追跡可能である必要があります。これを実現するために、識別子は機密コンテンツを公開する必要はありません。ビジネス目的との安定した関係と、各試行が実行されたポリシーを説明するのに十分な構成コンテキストが必要です。この継続性がなければ、チームは 1 つの頑固な操作を検討するのか、多くの新しいリクエストを検討するのか、あるいはその両方を検討するのかを判断するためにインシデント対応に時間を費やすことになります。追加のログ量は、必要な理解を提供することなく、新たなリソースのプレッシャーになります。

7. 進行中の仕事を探す

サービスはビジーであり、利用可能であると同時に役に立たない場合もあります。 CPU、接続使用率、リクエスト レートはアクティビティを表し、有用な完了は進行状況を表します。どちらのカテゴリーも他のカテゴリーに置き換わるものではありません。興味深い観察は、それらがどのように分岐するかです。固有の完了した操作が減少する一方で試行が増加する場合、サービスは、より少ない成果を上げるためにより多くの費用を費やしている可能性があります。作業の大部分が拒否されたためにのみレイテンシが改善する場合、アプリケーションは多くのリーダーに失敗しながらもリソースを保護している可能性があります。運用ビューでは、より安心できるストーリーを伝える指標のどちらかを選択するのではなく、両方の事実を可視化する必要があります。

分母は、再試行するアプリケーションにとって特に重要です。試行レベルの成功率は、操作ごとの試行回数によって歪む可能性があります。ユーザーレベルの完了率により、それぞれの成功を生み出すために必要なリソースの消費量を隠すことができます。便利なダッシュボードは、元の需要、試行合計、認められた作業、完了した独自の操作、有用な完了までの時間、および不確実な結果を分離します。また、これらの区別が決定に影響を与える年齢と仕事量のクラスも示します。これらの尺度はさまざまな質問を説明します。それらを収集することは、チームがそれらの変化をアクションに結び付けることができる場合にのみ役立ちます。

1 つの診断比率は、元の操作ごとに試行された依存関係呼び出しです。もう 1 つは、開始期限がすでに期限切れになっている操作に費やされる希少な実行時間の割合です。どちらも普遍的なサービス レベル目標として扱うべきではありません。これらは、疑わしいメカニズムを可視化する方法です。無害な接続回復を追加のビジネス実行としてカウントしたり、意図的に非同期タスクを放棄された作業として扱ったりすることを避けるために、定義は十分に正確である必要があります。この尺度は、インシデント ダッシュボードに別の魅力的な線を提供する場合ではなく、説明を区別する場合に価値があります。

コストもその観察の一部です。追加の試行により、追加のビジネス作業が完了しない場合でも、リクエスト料金、ログ量、接続チャーン、またはコンピューティング消費量が増加する可能性があります。再試行によって分母が大きくなると、リクエストごとのコストは改善したように見えますが、有用な結果ごとのコストは悪化します。組織には、失敗した作業や繰り返された作業を含めてタスクを十分に追跡するコストの観点が必要です。ここでは節約は要求されません。重要なのは、単に別のサービスや請求書に移行するのではなく、提案された復元力の変更によって無駄が削減されるかどうかを明らかにする会計境界を選択することです。

ループだけでなくチェーンをテストする

単体テストでの再試行が成功しても、相関障害が発生しているフリートについてはほとんど確立されません。より明確な制御されたテストでは、元の要求を識別可能な状態に保ちながら、依存関係のレイテンシーまたは完了能力を変更します。それは、増幅の試行が制限されたままであるかどうか、締め切りが意図したとおりに作業を終了するかどうか、および障害後に有用なスループットが回復するかどうかを観察します。環境と制限により、テストは安全になるはずです。目的は、堅牢性を示すために制御不能な生産インシデントを引き起こすことではありません。これは、多くの呼び出し元が一緒に失敗した場合でも追加の試行が引き続き役立つという特定の仮定に異議を唱えることです。

シナリオでは、遅い応答、明確な拒否、未知の結果を区別する必要があります。呼び出し元の期限前に回復する依存関係と回復しない依存関係を含める必要があります。キューベースのサービスでは、確認の不確実性、期限切れの作業、および意図的に制限されたリプレイも実行する必要があります。期待される結果は、送信されたすべてのタスクが最終的に成功するというだけではありません。一部のタスクは拒否するか、試行を中止する必要があります。意味のある質問は、制約されたリソースが保護されたままであり、組織が各クラスの作業に何が起こったかを説明できる一方で、観察された結果が契約と一致するかどうかです。

比較には同じ元の需要が必要です。それ以外の場合、より速く回復するように見える構成は、単にワークロードが容易になっただけである可能性があります。アカウントは、結果に関連する到着パターン、タスクの組み合わせ、依存関係の条件、および構成のバージョンを保持する必要があります。この記事のグラフなどの計算例と、実行テストで得られた測定値を区別する必要があります。もっともらしい数字の話をあたかもベンチマークであるかのように繰り返すと、証拠が薄れてしまいます。透明な小さなモデルが役立つのは、その滑らかなラインが生産痕跡に似ているからではなく、その仮定に疑問を投げかけることができるからです。

8. 挑戦をやめることを許されるシステム

最初の遅延リクエストに戻ります。停電になる必要はありませんでした。障害の連鎖は、いくつかの遷移を通じてその力を獲得しました。タイムアウトは、さらなる作業を開始する許可として解釈されました。共通の予算を持たずに複数の試行を重ねます。待機中の作業により、拡大する能力ギャップが隠蔽された。そして、復旧トラフィックは、その緊急性が追加のスループットを生み出したかのように扱われました。各遷移はチェーンを中断する場所を提供します。設計には、考えられるすべての反発パターンが必要というわけではありません。このサービスが不確実性を余分な負荷や反復的なビジネス効果に変える可能性がある点での制御が必要です。

状況によっては、別の試みがまさに正しい対応となる場合があります。短い独立した障害が消えたり、安全な読み取りが別のルートですぐに完了したり、制限された再送信によって貴重なタスクを回復したりする場合があります。この議論は永続性に反対するものではありません。それは、時間、能力、操作の意味を考慮した持続性のためです。サービスは、なぜ試行が行われたのか、その試行に対してどのような手当が支払われたのか、どのような観察によって次の試行が妨げられるのかを説明できる必要があります。この説明は、信頼性のために再試行が有効になっているという一般的な説明よりも役立ちます。

したがって、最も重要な回復能力は、停止する能力である可能性があります。期限を過ぎて結果が役に立たなくなった場合は、試行の作成を中止してください。無関係な作業から容量を借用するのはやめてください。ライブサービスに問題が発生し始めたら、バックログの再生を停止します。実行結果がまだ不明な場合に、明確な失敗を主張するのはやめてください。これらは異なる決定であり、それぞれに適切な所有者またはメカニズムが必要です。これらを組み合わせることで、未解決の意図をすべて同じ過負荷のパスに強制的に戻すのではなく、根底にある依存関係を回復し、組織が残っている作業を修正できる余地が生まれます。

信頼できるサービスは、永久に試行できるとは限りません。それはより現実的な約束をします。受け入れられた仕事には明確な意味があり、追加の努力には限界があり、失敗しても人々が理解して行動できる結果が得られます。これらの条件が当てはまる場合、再試行は、責任を負う顧客のいない目に見えないワークロードになるのではなく、有用なツールであり続けることができます。違いは回復中に最もはっきりと現れます。元の障害が解消されると、システムは自身の動作を十分に制御できるようになり、有用な作業を再開できるようになります。