RPC トーク: 電流制限の問題
マイクロサービス間の RPC 呼び出しは電流制限機能を使用することがよくありますが、多くの場合、非常に単純な電流制限戦略を使用するか、エンジニアが頭を悩ませて電流制限値を設定します。
この記事では主に、RPC レート制限における現在の問題と考えられる解決策について説明します。
なぜ電流制限が必要なのですか
カスケード クラッシュを回避する
ストレス テストを行ったサービスであっても、実際にオンラインで実行すると、受信するリクエスト トラフィックとロードできるトラフィックは一定ではありません サービス自体に自己保護メカニズムがない場合、トラフィックがロード後、ロードのこの部分はサービスのダウンストリームに渡され、連鎖反応または雪崩さえ引き起こします。
信頼できる応答時間の提供
一般に、サービスの呼び出し元にはタイムアウト期間があり、輻輳によってサービスがタイムアウト状態になると、最終的にサービスが正しい応答を返したとしても、Client にとってはまったく意味がありません。
呼び出し元に対するサービスのコミットメントには、応答の結果と応答時間の両方が含まれます。電流制限により、定格負荷容量の下で効果的な応答効率を維持するために、サービス自体がその負荷容量を超えてトラフィックを積極的に破棄することができます。
従来のソリューション
ファネル
アドバンテージ:
- 送信トラフィック レートを強制的に制限する機能
欠点:
- バースト トラフィックに対応できない
トークン バケット
アドバンテージ:
- 特定の平均速度を統計的に維持する
- トラフィックの短いバーストの通過をローカルで許可する
既存の問題
どちらのタイプの従来のソリューションでも、サービスが許容できる負荷を示すために固定値を指定する必要がありますが、最新のマイクロサービス アーキテクチャでは、サービスの負荷容量が次のように頻繁に変化しています。いくつかの一般的な理由:
- 新しいコードのパフォーマンスの変化に応じて変化
- サービスが依存するダウンストリームのパフォーマンスによって異なります
- サービスが展開されるマシン (CPU/ディスク) のパフォーマンスの変化に応じて変化する
- サービスによってデプロイされるノードの数に応じて変化します
- ビジネス ニーズの変化に合わせて変更する
- 時間帯により異なります
サービスの許容負荷値を手動で宣言すると、構成センターでこの値を動的に変更できるようになったとしても、それを維持することはできません。この値の選択には、人の小さな考えも含まれます.たとえば、サーバーは自分の能力を保守的に見積もったり、クライアントは自分のニーズを宣言しすぎたりします.長期的には、最終的な人為的な設定値は逸脱します.実情からです。
サービス負荷とは
サービスへのリクエストを開始するとき、次の 2 つのことを考慮します。
サービスがサポートできる同時並行リクエストの数
サービスの応答時間 同時
リクエストの数
サーバーについては、混同されることが多い指標がいくつかあります。
現在の接続数
現在受け付けているリクエスト数
現在同時に処理中のリクエスト数
SWC
接続数とリクエスト数は 1 対 N の関係にあります。現代のサーバーの実装では、接続自体が消費するサーバー リソースは非常に小さく (Java Netty 実装、Go Net 実装など)、一般にイントラネット サービスでは、多重化すると、要求の数が増加します。必ずしも接続数の増加につながるわけではありません。
一部のサーバーでは、トラフィック シェーピングのために、要求を受け取った直後に要求をサーバー応答関数に渡すとは限りませんが、最初にキューに追加し、サーバーがアイドル状態のワーカーを持った後に実行します。したがって、ここには 2 種類のリクエストがあります。承認されたリクエストと処理中のリクエストです。
また、QPS は統計指標であり、1 秒あたりに渡されるリクエストの数のみを示します。
現時点でサーバーの負荷に決定的な影響を与えるのは、通常、現在の同時リクエスト数です。
サービス応答時間
オンライン サービスが要求に応答するとき、それ自体が行う作業の抽象化は、次の 2 つのカテゴリに分類されます。
- 計算: 時間は CPU 周波数に依存し、固定値 (オーバークロックを考慮していません)
- 待機中: 時間は現在の並列リクエスト数に依存し、固定されていません
サーバーがリクエストに応答するアイドル スレッド/コルーチンを待機している
キュー 他のスレッドが競合するリソースを解放するのを待機している (おそらくロック、または占有されている CPU)
IO (ストレージ、ネットワーク) が戻るのを待機している (ダウンストリームのジッターに関係なく、この時間は通常固定値 )
上記の分析から、サービスの最終的な応答時間: RT = 作業時間 + 待機時間であることがわかります。
耐荷重の目安
次の図に示すように、マイクロサービスを入力パイプと出力パイプとして抽象化できます。
真ん中の水道管の「耐荷重」は、実際には水道管の容積(管径×管長)であり、数値化できる指標です。
オンラインで遭遇する状況は実際にこの水道管に似ています.今私たちがする必要があるのは、サービスの負荷容量を推定するために、水道管の容積を計算するのと同様の定量的な方法を見つけることです.
ここで、特定の 2 番目の時間枠内でサービス インスタンスを観察すると、次の 2 つの値を簡単に取得できます。
- QPS: この 1 秒間のリクエスト数。単位は req/s です。
- AvgRT: この秒の平均リクエスト応答時間 (ミリ秒)。
リトルの法則(リトルの法則)によると:
安定したシステム (L) では、長期の平均顧客数は、長期の実効到着率 (λ) にシステム内の顧客の平均待ち時間 (W) を掛けた値に等しくなります。
この法則は、安定したリソースに制約のあるシステムのスループットを計算するために使用されます。
私たちのシステムでは、このルールを使用して、スループット = QPS * (AvgRT / 1000)を取得できます。その中で、AvgRt / 1000 はミリ秒を秒に変換します。
この式を別の角度から理解するために、現在サーバーによって処理されている (インフライト) リクエストの量がこの値を超えないことを保証できれば、各リクエストの平均応答時間も理論上の AvgRt について (飛行中の速度 ~= 水から出る速度)。この最終的に計算された量は、サービスの現在の負荷の見積もりを取得したいものです。また、サービスに負荷がかかり始めたときにのみ、現在の負荷状況を負荷容量と見なすことができます。
インフライト、RT とスループットの関係
ほとんどのオンライン サービスでは、Inflight と RT およびスループットの関係には、次の 2 つの段階があります。
- リソースの制約 (CPU/ディスク/ネットワーク/メモリ) がない場合、インフライトが大きくなっても、一般に RT は大きく変化せず、スループットが増加し始めます
。 - インフライトが成長し続け、リソースの競合が発生すると、インフライトが増えるにつれて RT が増加しますが、
限られたリソースは限られたことしか実行できないため、スループットは大幅に変化しません。
上記の現象によると、3 つの座標図を描くことができます。
最初の 2 つの図は、サーバーの実際の現象を反映しています。3 番目の図は、最初の 2 つの図の同じ横座標を削除し、RT とスループットの関係を個別に示しています。3 番目の図は、スループットの向上と引き換えに RT 損失を使用するという、現在の制限作業の本質を示しています。
より現実的な図は次のとおりです。
ここで傾きが小さいほど、RT 損失のこの部分の費用対効果が高くなります。私たちの電流制限戦略は、この最適な電流制限点を見つけることです。
エンジニアリングの実践
上記の分析は、理論モデルに基づいた導出にすぎません.実際のエンジニアリング アプリケーションでは、次の現実を考慮する必要があります。
スロットリングを開始する時期
最初にリソースの競合がない段階では、フロー制御を行う必要はありません。したがって、フロー制御ロジックをトリガーするために、サービスが着信競合のビジー状態に入ったことをマークするには、ヒューリスティック インジケーターが必要です。一般に、次の一般的なインジケーターを選択できます。
OS Load1
CPU 使用率
平均 RT 値
スレッド数
QPS
RTの選択
RT = 作業時間 + 待機時間という式が以前に推測されていました。そして、ここでの待ち時間も、待機。
ただし、RT は 1 つのリクエスト指標にすぎません. スループットを計算するために必要なのは、統計的な RT 値です. このとき、AvgRt、MinRT、または P95RT の選択は、詳細ではありますが非常に重要なことです.
スイッチやルーターなど、性能が非常に安定しているシステムであれば、パケットは互いに影響を与えないため、このタイプのシステムの RT = 稼働時間 + キューイング時間 となります。また、キューイング時間をできるだけ短縮したい (必要がないため、全員がキューイングし、より多くの輻輳が発生します)。この場合、RT は MinRT を使用することを選択できます。これは、MinRT が固定時間に最も近いためです。これは、Google BBR アルゴリズムで使用される値でもあります。
ただし、ビジネス サービスの違いは、リクエスト間で CPU とストレージの競合が発生するだけでなく、ロックの競合などの問題が発生する可能性があることです。問題のこの部分により、競合の待ち時間が非常に不確実になり、ジッターが頻繁に発生し、予測できなくなります。MinRT を引き続き使用すると、サービスの同時実行機能が過小評価されることになります。
このプロセスをより直感的に体験できる例を挙げてみましょう。ある大学では、毎年 1,000 人の大学院生を 2 年制で募集していますが、試験が難しすぎて平均 3 年で卒業することになります。現時点では、大学が同時に収容できる大学院生の数を計算することは明らかに適切ではありません。
しかし、AvgRT を直接使用できるということではないでしょうか? 実際にはそうではありません. 電流制限を正確なポイントでスタックさせることは困難です. カードが本当に正確であっても、それは低い耐障害性につながります. そのため、電流制限はシステムの負荷容量をわずかに過小評価する傾向があります。Bilibili は、パブリック マイクロサービス フレームワークの Kratos で、各サンプリング ウィンドウの AvgRT の中で最小の AvgRT を使用します。Ali's Sentinel は、本当の意味で最小の RT を使用します。
実際のビジネス特性に応じて RT インデックスを選択した後、以前にカウントされた QPS を掛けてスループット値を取得できます. このとき、インフライト > スループットを直接破棄する限り、適応的で科学的な測定基準を使用できます。フローポリシー。