分散サービスで「リトライストーム」を回避する方法


10

「再試行ストーム」は、クライアントが設定された回数再試行するように設定された場合に発生します。サービスの通常の動作ではパケット損失が発生するため、再試行ポリシーが必要です。

この例を見てみましょう:

サンプルアーキテクチャ

たとえば、サービス全体が1秒あたり80,000リクエストをサポートし、キャパシティの約80%で実行されるようにスケーリングされている場合、サービスが1秒あたり101,000リクエストを受信する原因となったトラフィックのスパイクにより、1,000リクエストが失敗します。

再試行ポリシーが有効になると、エラーが検出された場所に応じて、追加で1,000以上のリクエストが発生し、サービス全体として1秒あたり最大102,000のリクエストがプッシュされます。毎秒失敗したリクエストの数。

予測されたピークトランザクションを超えるサービスの大規模な過剰プロビジョニング以外は、非効率的です。「リトライストーム」を回避するためにどのような戦略を採用できますか?


100kQPSが容量の80%である場合、101kQPSは1kの障害にならず、障害はゼロにすべきです-オーバープロビジョニングのポイントではありませんか?
エイドリアン

@エイドリアンあなたの権利、それはポイントを説明するための不自然な例でした-私は過度に抽象的でなくても私のポイントを明確にするのに十分還元的であるように努めていました。「100,000をサポートするようにスケーリング」を「80,000をサポートするようにスケーリング」に修正しました。
Richard Slater

回答:


7

それはあなたが避けようとしていることに依存します。

本当に重要なサービスであるサービスの中断を回避しようとしている場合(「API呼び出しが適切に提供されない場合、人々は死ぬだろう」と考えています)、その大きな非効率性のために予算を組む必要があります。専用リソースを非常に過剰にプロビジョニングすることで発生します。そして、はい、それらは専用である必要があります。これのどれもがトラフィックの急上昇に対応することができず、複数のサービスの急上昇はそれ故に停止を引き起こします。

サービスがダウンしているというはるかに可能性の高いシナリオでは、クライアント側とサーバー側の両方から問題に対処できるので不便です。大量のトラフィックの問題を実際に解決することは論理的に不可能であることは注目に値しますが、トラフィックを処理しないと(リソースを消費します)、それが再試行であるかどうか、成功したが誤って処理された要求の再試行であるかどうかを知ることができないためです。クライアント(DDOSの場合など)によるものです、影響軽減することができます。

クライアントコード上限と正常障害のための機構を有している賢明な再試行ロジックを書きます。そうすることで、失敗したリクエストの無限ループにユーザーを追い込まずに、エラーを出して、ユーザーが少しの間やったことをすべて試すように指示するだけです。

あなたのためにサーバー側のインフラ最も簡単な解決策は、スロットルにあります。リクエストに対するハード制限。特に、特定のユースケースに基づいて論理的にリクエストを分散できる場合(つまり、集中サービスでいくつかの難しい決定を行っている場合、地理的に離れたリクエストのブロックを開始して、スレッドがハングする可能性がありますか?サーバー側ですか、それとも、不可避であるがわずかな停止を均等に分散しますか?など)基本的に、意図的にゲートウェイから503を返すことは、リクエストを通過させて504を送信するよりもはるかに安価なことです。とにかく。基本的に、クライアントが現在提供できることに基づいて動作するようにクライアントを強制し、クライアントが適切に反応できるように正しい応答を提供します。


5

これらの再試行ストームを防ぐ1つの方法は、バックオフメカニズムを使用することです。

以下からの再試行にバックオフを実装 Google App Engineのセクションのスケールのためのデザインガイド:

Cloud Datastoreなどのサービスを呼び出すか、URLフェッチまたはSocket APIを使用して外部サービスを呼び出すかに関係なく、コードは失敗時に再試行できます。これらの場合、雷の群れの問題を回避するために、ランダム化された指数バックオフポリシーを常に実装する必要があります。最大再試行制限に達した後は、再試行の総数を制限し、失敗を処理する必要もあります。

ほとんどのGAE APIでは、このようなバックオフメカニズム/ポリシーがデフォルトで有効になっています。


おかげで、バックオフメカニズムを実装することは素晴らしいアドバイスです。私は通常、一時的なフォルト処理アプリケーションブロックを使用して、構成可能な指数バックオフを行います。ただし、Azureでハイパースケールアプリケーションを操作した5年以上の運用経験を通じて、たとえ指数バックオフが導入されていても、「リトライストーム」は依然としてかなり頻繁に発生します-それらを回避するための実行可能な戦略を見つけることはできませんでした。
Richard Slater
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.