舞台裏: OCI NAT Gatewaysでノイジー・ネイバーをミュートに (2024/06/27)
舞台裏: OCI NAT Gatewaysでノイジー・ネイバーをミュートに (2024/06/27)
https://blogs.oracle.com/cloud-infrastructure/post/behind-the-scenes-oci-nat-gateways
投稿者: Michal Karczmarek | Consulting Member of Technical Staff, OCI Networking Service
皆さんは、今までの話し合いに集中しようとして重要な会議に出たことがありますか?突然、おしゃべりな同僚のバックグラウンドノイズが圧倒的に気を散らすことになります。彼らの絶え間ないおしゃべりは会話の流れを混乱させ、誰もが集中することを困難にします。トータルバズキルですよね。このシナリオは、マルチテナント・クラウド環境におけるノイジー・ネイバーの問題を反映しており、単一の顧客のトラフィック・スパイクによって波及効果が生じ、同じリソースを共有する他の顧客のエクスペリエンスに影響を与えます。
このノイジー・ネイバー問題は、クラウド・サービス・プロバイダとその顧客にとって大きな頭痛になる可能性があります。ほとんどのクラウド・サービスは、共有リソースを使用して運用するように設計されており、ミーティング・ルームの誰もが、中断することなく話し合う公平な機会を得られるように、専用のリソースの幻想を顧客に提供します。ただし、バックグラウンド・ノイズによって会議が中断される可能性があるのと同様に、クラウド内のノイジー・ネイバーは、リソース割当てを最適化する取組みにも関わらず、サービスのパフォーマンスを低下させる可能性があります。
私は、Oracle Cloud Infrastructure(OCI)のネットワーク・アドレス・トランスレーション(NAT)ゲートウェイでリード・エンジニアの1人です。つまり、サービスに何か悪いことが起こり始めると、ページが手に入ります。その結果、お客様に優れたスムーズなサービスを提供することがいかに重要か、私は深く認識しています。これには、お客様がノイジー・ネイバー問題を抑制できるよう支援することが含まれます。ノイジー・ネイバー問題を排除することは、サービスが不必要に高価であるか、クラウド・サービスを非常に価値のあるものにする弾力性と柔軟性のいくつかを失うことを意味する可能性がありますが、ノイジー・ネイバーを他の顧客から隠しながら、クラウドの有益なプロパティを保持するためにNetwork Address Translation(NAT) Gatewayを構築しました。会議にモデレーターがいるようなもので、誰もが注文と効率を維持しながら話す機会を得るのに役立ちます。最良の部分?OCIは数年にわたる指数関数的な成長に直面していますが、NAT Gatewayは時間のテストに立って、不要なスロットルなしでノイジー・ネイバーの問題に対処することに成功しました。
このブログ投稿では、OCIのNAT Gatewayが、あるカテゴリのノイジー・ネイバーの問題を堅牢に解決した方法について説明します。これは、熟練したモデレーターが平和を回復し、中断された会議を命令するようなものです。
ネットワークNAT Gateway
クラウド環境では、お客様は仮想ネットワーク・インタフェース・カード(VNIC)を使用してネットワークに接続されたコンピュート・インスタンスをプロビジョニングします。多くのお客様は、セキュリティー上の理由から、VNICにパブリックIPを割り当てたくありません。パブリックIPを持つことは、インターネット・トラフィックがVNICに到達して、攻撃に対して脆弱になる可能性があることを意味します。これらの攻撃を防ぐためにVNICセキュリティ・ルールを構成できます。ただし、顧客は多くの場合、インターネットにルーティングできないプライベートIPのみをVNICに割り当て、NAT Gatewayを使用してインターネットにアクセスすることを好みます。
NAT Gatewayには、インターネットに接続可能な単一のパブリックIPがプロビジョニングされ、すべてのインターネット接続に使用されます。受信接続は許可されません。ファイアウォールの形態として機能し、発信接続のみを許可し、お客様に安心してご利用いただけます。
図1: インターネットおよびNAT Gatewayの顧客ビュー
NAT Gatewayは、パケットの転送と接続の記憶という2つのジョブを実行するために連携する複数のサーバーで構成されます。
パケットの転送は、サービスのより単純な部分です。パケット自体に対して行う作業は、サーバーに対してローカルであり、パケットを処理するメモリーは必要ありません。当社のソフトウェアは高度に最適化されており、毎秒数百万のパケットをルーティングできます。
1つのサーバーでは不十分であるため、接続を記憶することは難しいことです。そのサーバーをメンテナンスのために停止した場合、接続は切断され、お客様は不幸になります。かわりに、各接続は複数のサーバーによって記憶されます。現在、メンテナンスのために1つのサーバーを停止した場合、サービスは接続のメモリーを保持し、顧客は決して賢くありません。接続について複数のサーバーに通知するプロセスは、レプリケーションと呼ばれます。
接続のレプリケートには時間とリソースが必要です。その結果、パケットを処理できる接続数よりも、1秒当たりのレプリケーション数が大幅に減少します。多くの接続を開いているお客様は、レプリケーション専用のリソースをすべて使い切って、騒々しい隣人になることができます。負荷が小さい場合でも、他の顧客は接続が切断されたことを確認できます。
図2: NAT Gateway・レプリケーションの概要
顧客の小規模なサブセットがサービスのリソースに負荷をかける場合、サービスは、どのリクエストが優先され、どのリクエストが削除されるかを判断する必要があります。このシナリオでは、サービス・アーキテクトが明示的に選択しない場合でも、サービスはイベント中に選択します。明示的なスロットルがない場合、顧客は先着順で提供されます。すべての顧客は、同じ割合のリクエストを処理できますが、ビジー状態の顧客は、ほとんどがアイドル状態の顧客よりもスループットが高くなります。その結果、アイドル状態の顧客は騒々しい隣人の問題を経験し、忙しい顧客は、サービスを悪用している顧客ではないにもかかわらず、その経験に影響を受けます。このシナリオは、計画に典型的な失敗であるため、失敗を計画します。
ノイジー・ネイバーの問題を解決するためのOCIのNAT Gateway要件
NATのノイジー・ネイバーに対するソリューションを検討する際、次の要件に達しました。
- システムがビジー状態の場合にのみアクティブ化し、システム全体の負荷を100%近くに抑えるソリューションが必要でした。 この目標は、できるだけ多くの資源を利用することを可能にします。
- システムに大きな負荷をかけているお客様にのみ影響を与えるソリューションを求めていました。これはノイジー・ネイバーを避けるための定義です。
- 私たちは、システムへの応答時間が迅速になるよう求めていました。負荷の変化とスロットル応答の間隔は、顧客がノイジー・ネイバーの影響を感じる時間です。応答時間が長くなるほど、ノイジー ネイバーが見えるようになります。
- アルゴリズム自体はシンプルでローカルであり、必要なリソースはほとんどありませんでした。また、私たちは、優れたサービスを提供するために、多くのリソースを利用したいと考えています。シンプルさは、正確性とメンテナンス性の鍵です。
ノイジー・ネイバーの影響を軽減するための従来のアプローチ
これらは、ノイジー・ネイバーの影響を軽減するために一般的に使用される従来のアプローチの一部です。
- 正確なプロビジョニング: 1つの簡単なアプローチは、バースト・ケースの場合でも、顧客ごとに十分なリソースを割り当てることです。まるで会議室に席を割り当て、誰もが自分のスペースを確保するようなものです。このアプローチの欠点は、ほとんどの顧客がすべてのリソースを使用せず、空席が無駄になるような大量のリソース無駄になることです。
- リバランスのロード: 顧客の負荷をシステム内を移動して、リソースを大量に利用できるようにすることもできます。そのようなシステムの導入は、うまくいきません。ミーティング中に席を再編して会話フローを最適化するとします。トリッキーですね。また、クラウドでの顧客の負荷の再分散についても同様です。顧客の移動は混乱を招く可能性があり、顧客の配置に関するグローバルな迅速な意思決定は困難です。
- シャッフル・シャーディング: このアプローチでは、顧客の負荷が多くのシャードに分割され、サービスは同じ2人の顧客のシャードを複数のシステムでスケジュールすることを避けようとします。そのため、各顧客は、他の顧客のエクスペリエンスのごく一部にのみ影響します。会議室を小さなグループに分けて、一人のノイジー・ネイバーが集まり全体に与える影響を制限していると考えてください。このアプローチによって影響を受ける顧客の数が減りますが、問題は解決しません。ノイジー・ネイバーは依然として騒々しく、その顧客とリソースを共有する人は誰でも影響を受け、別のアプローチとペアリングする必要があります。
- スロットリング: 古いソリューション!一部のお客様が特定のシステムのリソースを圧倒していることに気付いたら、スロットルを試すことができます。システムの負荷量を測定し、負荷がしきい値を超えるとすべての新しい要求を抑制できます。いくつのリクエストを削除する必要がありますか。それとも、忙しい顧客を特定し、それらを抑制するだけでいいのでしょうか?顧客をどれだけ抑制すべきか。では、どうすれば忙しい人を素早く特定できるのでしょうか。まるで、そのおしゃべりな同僚のボリュームを下げ、スポットライトを当てないようにしているようなものです。しかし、正しいバランスを取ることが本当の課題です!
基本的に、負荷の合計を処理するのに十分なリソースがないノイジーネイバーの問題に対するすべての解決策は、何らかのスロットルになります。スロットルにより、サービスの動作が変更されます。スロットルされた顧客は、処理に成功したリクエストの数が少ないため、サービスが悪くなると認識しています。
リストされている解決策はどれも、私たちのニーズにかなり当てはまりません。そこで、迅速、効率的、シームレスなスロットル・ソリューションを構築する取り組みに着手しました。
キュー理論と否定的なフィードバック
大学院の学位を勉強しているとき、私はシステムモデリングのコースを取った。システムをモデル化するために使用したソフトウェアは不十分でしたが、我々はキュー理論の基本をいくつか研究しました。私が覚えている興味深い教訓の一つは、常に中途半端にキューを埋めることは難しいということです。リクエストが消費されるよりも早く到着すると、キューは一杯になります。リクエストの受信速度が消費速度よりも遅い場合、キューはほとんど空のままになります。キューが途中でいっぱいになるようにするには、リクエストが到着したのと同じレートで消費される必要があります。
NAT Gatewayでは、到着したリクエストは、新しい接続を開こうとしているお客様で、消費されたリクエストは、正常にレプリケートされた接続です。オラクルのサービスは、お客様がレプリケートできる以上の新しい接続を開こうとしていた際に問題が発生しました。それで、スロットルの質問は、レプリケーションの速度に一致し、ノイジー・ネイバーの接続のみを削除するように、どの新しい接続を削除するかを選択する方法になりました。
ノイジー・ネイバーの問題を解決する前でも、当社のサービスはすでにキューを使用してパケット処理スレッドと接続レプリケーション・スレッドの間でデータを渡していました。そのため、キューの観点から問題を考えると、ほとんど作業を必要としないソリューションを作成するチャンスがありました。
エレクトロニクスでは、単純な回路は、アンプを制御するために負のフィードバックと呼ばれる技術を使用します。負のフィードバックは、監視者がシステムの出力の一部がターゲットから離れていることを判断し、ドリフトに対抗するアクションを実行するメカニズムです。負のフィードバックメカニズムの最も一般的な例はサーモスタットです: 冬に気温が設定されたターゲットを下回ると、ヒーターがオンになります。ヒーターは気温を目標値に戻し、サーモスタットはヒーターをオフにします。
実生活では、私たちは毎日ネガティブなフィードバックを使っています。車が運転中に車線に漂っていることに気付いた場合は、車線を中央にゆっくりと戻します。これは否定的なフィードバックです。否定的なフィードバックの難しさは、それが完璧ではないということです。初心者の運転手は、隣の車線に横切るまで車線で漂流しているとき、または横に横切って横断しているとき、ひっくり返る傾向があるかもしれません。サーモスタットでさえ、ヒーターが遅すぎて家を過熱させたり、手遅れになったり、家が冷たくなりすぎたりする可能性があります。
システムがビジー状態になったときにキューが部分的にいっぱいになるように、ネガティブなフィードバックメカニズムを適用したいと考えていました。困難は、私たちの要求をすべて満たすためにどのようにそれをするかでした。
顧客ごとの調整可能なトークン・バケット
アルゴリズムでは、トークン・バケットを使用して、各顧客が新規接続をオープンするレートを追跡します。トークン・バケット・スロットルは、業界で使用される標準技術です。基本的な考え方は、固定容量バケットに一定のレートでトークンが一杯になることです。バケットがいっぱいになると、トークンは累積を停止します。リクエストが到着すると、バケットからトークンが取得されます。バケットが空の場合、リクエストは削除されます。
図3: トークンバケットアルゴリズム
トークン・バケットの実装は調整可能です。バケットの容量とトークンが到着するレートの両方を変更できます。スロットル・レートとバースト・サイズなどのパラメータは、お客様ごとに個別に設定できます。スロットル・レートよりも早く新しいフローを開始する顧客は、ある程度の低下を経験します。最も単純な実装では、すべての顧客に同じ設定を使用します。そのため、スロットルが必要な場合、忙しい顧客のみを抑制できます。
アルゴリズムの2番目の部分では、各顧客を抑止するための適切な料金を選択する必要があります。高すぎるレートを選択すると、システムは圧倒的に増加します。低すぎる料金を選択する場合、少数の接続をオープンしている顧客を不必要に抑制します。ここでは、前述したキューの深さに基づいてスロットル・レートを決定します。各顧客を個別に抑制したいのですが、リクエストの割合を合わせると、システムが処理できるリクエストの割合と正確に一致します。その後、キューの深さは一定になります。
最も単純な実装では、キューが完全にいっぱいになるようにし、キューは常に満杯になります。その時点で、キューのサイズはほとんど問題になりません。短期的な変動に対応するのに十分な大きさである限り、その最大サイズはシステムの全体的なスループットに寄与しません。キューがいっぱいになると、すべての顧客のスループット制限が低くなるネガティブ・フィードバック・ループを設定できます。スロットルの制限が低すぎる場合、キューはさらに増え、制限が低くなります。スロットルの制限が大きすぎる場合、キューは空になり、制限が引き上げられます。スロットル・レベルは、キューで許可されるエントリの数を効果的に制御します。キューに一貫して少数のエントリが含まれている場合、レプリケーション・ストアはフル・キャパシティで動作しているため、振動やその他の副次的影響の可能性は低くなります。
残りの部分は、キューの深さをスロットルに変換する方法を理解することです。単調に減少する(右下に移動する)カーブを使用し、キューがいっぱいになったときに0に達すると、カーブは機能します。キューが比較的空の場合、オペレーティング・リージョン内のスロットルされていない領域をいくらか許可することをお薦めします。このスペースは、キューを埋めることができず、時折短期間のスパイクで顧客の通常の動作に対応します。また、レプリケーション・システムがわずか1秒でキューを排出できるようにするために、キューのサイズも調整しました。そのため、顧客が重大なレイテンシ・スパイクを観察せずに、キューを少し埋めることができます。
図4: スロットル応答の例
最後のアルゴリズムでは、ルータがNATの新しい接続をレプリケートする場合、それらのキューがどれだけいっぱいであるかを確認します。これらのキュー・レベルに基づいて適切なレベルの顧客ごとのスロットルを検索し、顧客のバケットでポート割当てのレプリケートが許可されているかどうかを確認します。異なるキュー・レベルのスロットル・レベルは、初期化時に事前計算されます。
このアルゴリズムは平衡を求め、負のフィードバックを使用してそれを見つけるので機能します。新しいリクエストを受け入れ、それらをレプリケートしてキューから削除するよりも速くキューに配置しているかぎり、キューの深さが増え、スロットルが増えます。レートが一定の場合、最終的にこの均衡レートが見られ、キューの深さは一定のままです。キューの深さが減少すると、新しい平衡が見つかるまでスロットルが減少します。
このアルゴリズムのすべての決定はローカルで行われますが、分散システム全体を適切に機能させるスロットルを生成するのに適しています。決定はローカルですが、決定を行うために使用されるデータには、すでにグローバル・スループットの状態に関する残りの情報が含まれています。たとえば、サービスがスループット容量の半分を失った場合、顧客の動作が変更されていなくても、キューがいっぱいになることがあります。この動作は、リクエストが受け入れられるのと同じレートでレプリケートされる新しい平衡がシステムによって見つかるまで続行されます。このシステムはまた、このアルゴリズムのもう一つの有用な特性である適応性も示している。同じアルゴリズムを異なるCPU速度でサーバーにデプロイしており、実装を変更する必要はありません。
このアルゴリズムにより、次の制限目標を満たすことができました。
- スロットルは、システムがビジー状態の場合にのみアクティブ化されます。システムがビジーでない場合、キューは空になり、すべての顧客はスロットルされません。
- 顧客ごとに別々のバケットを維持し、マイナスのフィードバックを使用してスロットルを設定することで、私たちは最も忙しい顧客を抑えるだけです。
- リクエスト・キューは、レプリケーション・システムのビジー状態を瞬時に把握し、リクエストごとにこの情報を確認します。つまり、状況の変化に対するレスポンスはほぼ瞬時になります。
- アルゴリズムは理解しやすく、実装も簡単でした。すでにローカルで使用可能なデータを使用し、新しい依存関係や複雑なメカニズムを追加する必要はありませんでした。
必要に応じて、このアルゴリズムを使用して、異なる顧客に異なるスロットル曲線を割り当てることもできます。これにより、お客様をさまざまなレベルのサービスに分類し、さまざまなポイントや料金で抑制を開始することができます。たとえば、無料層の顧客は常にスロットルされる場合がありますが、有料の顧客は、キューが75%満杯の場合にのみスロットルが表示されます。この例では、フリー層の顧客にノイズの多い支払顧客ネイバーがあるが、階層スロットルの自然な結果である状況を設定します。
図5: 顧客層ごとに異なるスロットル・レスポンスの例
並列性
ルータが少し単純化されていることを示す図5。私たちのルーターには多くのパケット処理スレッドがありますが、レプリケーションスレッドは1つだけです。そのため、ルーターのフリート全体だけでなく、すべてのスレッドにわたってスロットルを実行する必要があります。これは、アルゴリズムが非常に適応的であるため、あまり問題になりません。各パケットスレッドは、レプリケーションスレッドに独自のキューを取得します。各パケット・スレッドは、独自のスロットルを実行し、独自のキューのみを見て、そのスレッドについてのみ各顧客のスループットを測定します。レプリケーション・スレッドは、異なるスレッドからの接続をかなりレプリケートしようとします。通常、キューはスレッド全体で均等に増加します。つまり、各スレッドが同様のレベルのスロットルを設定します。ただし、1つのキューがバックアップを開始すると、そのキューに接続するパケット・スレッドは停止し、レプリケーション・スレッドは、他のキューがほとんど空のままであってもビジー状態のままになります。
図6: 並列性を備えたNAT Gatewayレプリケーション
リアルタイムの結果
数年前、私たちのサービスは最も忙しい地域で大きな負荷の急増を経験しました。サービスの中小企業として、私はつぶやきました。数分かけてダッシュボードを見てみると、すべてが完璧に機能していることに気付き、アラームの原因はありませんでした。さらに調査の結果、最大のお客様がルーティング・テーブルを誤って構成し、動的ルーティング・ゲートウェイ(DRG)を介してオンプレミス・データ・センターにトラフィックを送信するのではなく、NAT Gatewayに送信したことが判明しました。提供される負荷のレベルは、処理するハードウェア・リソースの数倍でした。異常な活動に対して警鐘を鳴らしていましたが、他のお客様は何らかの停止について不満を抱いていませんでした。
私たちのスロットルアルゴリズムは時間の英雄でした。エンジニアがインシデントを調査し、エグゼクティブが他の誰に支援を依頼するかを把握していましたが、オラクルのアルゴリズムは、誤った構成をした顧客を即座に隔離し、サービスを問題にしないよう抑制しました。広範囲にわたる停止は発生せず、他の顧客に通知する必要もありませんでした。サービスは決して影響を受けませんでした。
まとめ
本記事では、お客様を相互に保護し、お客様をインテリジェントに選択してお客様からサービスを保護するために、当社のサービスの1つで使用するスロットル・アプローチについて説明しました。このアプローチは、すべてのリクエストで評価される否定的なフィードバック・ループを利用することで、業界で見つけた他のアプローチよりも効果的です。私たちは、すべてのリソースを利用できるので、否定的なフィードバックアプローチを選択しました。弊社のアプローチの評価コストは非常に低いため、システムの負荷と個々のお客様のスループットに対してすべてのリクエストを評価し、リクエストの処理を許可するかどうかを決定できます。この組み合わせにより、非常に安定した効果的なスロットルメカニズムが実現します。
当社は、地域のお客様が隣人のために減少を経験する可能性がある場合に、スロットル・アルゴリズムの検索に着手しました。このアルゴリズムを実装して以来、ドロップに関する正当な苦情は受けていません。実際、私たちは、他のお客様が気付かずに、当社のサービスに大量のリクエストを送信した最大のお客様の一人を生き残りました!
スロットルは、私たちの問題の一部に対する解決策にすぎません。オラクルのフリートがこのスロットルの動作を体験し始めると、オペレーション・チームは引き続きトラフィックを評価し、お客様と関わる必要があるのか、それともサービスにハードウェア・リソースを追加する必要があるのかを決定する必要があります。一方、スロットルにより、サービスが停止するのを防ぎ、すべてのお客様がリソースを最大限に活用できるようになります。
このブログ・シリーズでは、優れたクラウド製品の提供に向けた、新しいプロジェクト、課題、および問題解決のOCIエンジニアが直面している課題について説明します。OCIエンジニアリング・シリーズの後ろには、Oracle Cloud Infrastructureで働く有能なエンジニアが参加する、同様のOCIエンジニアリングの詳細が記載されています。
詳細は、次のリソースを参照してください。
コメント
コメントを投稿