ホームページ  >  記事  >  バックエンド開発  >  ThrottleX: 苦労せずに 1 秒あたり 100 万件のリクエストに拡張

ThrottleX: 苦労せずに 1 秒あたり 100 万件のリクエストに拡張

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-22 14:59:03434ブラウズ

自分でテストしたい場合は、下にスクロールしてください!!

紹介:

1 秒あたり何百万ものリクエストを処理しますか?それは可能ですか? ?

大規模な分散システムについて話すと、物事が…複雑になることがあります。ご存知のとおり、レート制限は悪用を防ぐために不可欠ですが、多くの場合ボトルネックになります。 1 秒あたり 100 万リクエスト を滞りなく処理できるシステムを設計したと言ったらどうなるでしょうか? Go で書かれたオープンソースの分散レート制限ライブラリである ThrottleX を紹介します。

この投稿では、カーテンを引いて、私たちがこの驚くべき規模をどのように達成したかを正確に説明します。高度な最適化、それをすべて可能にした Go 同時実行モデル、そして途中で遭遇した意外なボトルネックについても説明します。しかし、これは単なる理論ではありません。私たちが達成した実際のベンチマークを共有します。もうすぐ限界を突破するので、しっかりしてください! ?


セクション 1: 課題 – スケールが重要な理由

スケーリングレート制限は、極端なスケールで実行してみるまでは簡単そうに見えるものの 1 つです。ほとんどのシステムは、1 秒あたり数百または数千のリクエストを処理できます。しかし、何百万ものリクエストに達すると、事態は急速に崩壊します:

  • メモリ管理の問題 ?
  • ネットワークのボトルネック ?
  • 同時実行の悪夢 ?

その秘訣はレートを制限するだけではなく、複数のノードにわたって効率的に実行し、利用可能なリソースをすべて消費することなくすべてのリクエストが超高速で処理されるようにすることです。そこで ThrottleX が登場します。速度を重視して構築され、規模を考慮して設計されており、レート制限アルゴリズムとリアルタイムの最適化を組み合わせて使用​​して、ゲームの先を行き続けます。

しかし、なぜこれが重要なのでしょうか?実際のシナリオをいくつか見てみましょう:

  • 高負荷下の API: API はアプリのバックボーンであり、トラフィックが急増したとき (こんにちは、バイラルモーメント! ?)、すべてをダウンさせることなくその流入を処理する方法が必要です。
  • 分散マイクロサービス: サービスが外部 API に依存している場合、数百万のリクエストにわたって一貫したパフォーマンスを確保することで、システム全体の安定性が維持されます。
  • クラウド スケール アプリ: クラウド インフラストラクチャでは、予測不可能なワークロードを管理しながらコストを最適化する必要があります。ここで、効率的なレート制限が危機 (クラウドの料金も?) を節約します。

ThrottleX は単なるレート リミッターではありません。極端な条件向けに設計されており、どのようにして限界まで押し上げたかを正確に説明します。


セクション 2: 概要 – ThrottleX のアーキテクチャ

ThrottleX の中心となるのは、スマートなレート制限アルゴリズムの組み合わせと高度に最適化された同時実行モデルです。しかし、重要なのはアルゴリズムだけではありません。アルゴリズムがどのように実装され、分散環境全体でどのように拡張可能にするかが重要です。すべてを機能させる中核となるアーキテクチャを詳しく見てみましょう。

1.魔法の背後にあるアルゴリズム

レート制限に関して言えば、おそらく次のような古典的なものを聞いたことがあるでしょう。

  • トークン バケット: トラフィックのバーストは許容されますが、トークンは一定の速度で補充されます。
  • スライディング ウィンドウ: 時間の経過とともにトラフィックを平滑化し、スライディング時間間隔でリクエストをカウントします。
  • 漏れのあるバケツ: 穴の空いたバケツのようなものだと考えてください。リクエストは一定の速度で「漏れ」ます。

ThrottleX は車輪の再発明はしませんが、これらの実証済みのアルゴリズムを採用し、よりスマートにしました。その方法は次のとおりです:

  • 動的レート制限: トラフィック状況に基づいてレート制限をリアルタイムで調整できる柔軟なシステムを実装しました。トラフィックが突然急増した場合でも、ThrottleX はオーバースロットルを発生させずに負荷を処理し、最適なスループットを実現します。
  • 同時処理:同時リクエストを処理する場合、レート制限は特に注意が必要です。 ミューテックス ロックを使用して、最大限の同時実行を可能にしながら競合状態が発生しないようにしました。

2. Go 同時実行モデル – 秘密のソース

ThrottleX が Go に組み込まれている理由の 1 つは、その ゴルーチンチャネル であり、最小限のオーバーヘッドで驚異的な同時実行性を実現します。 Go の同時実行モデルが私たちにとって大きな変革をもたらした理由は次のとおりです:

  • Goroutine は安価です: 従来のスレッドとは異なり、Goroutine のメモリ使用量はわずかです。これは、システム リソースを破壊することなく、何百万ものそれらを生成できることを意味します。
  • 非同期処理: リクエストを非同期に処理することで、操作のブロックを回避します。これは、高トラフィック下で ThrottleX の応答性を維持するための鍵です。各リクエストは独自の goroutine で処理され、チャネル によりチャネル間の通信が促進され、スムーズな調整が行われます。

平たく言えば、超効率的な組立ラインのようなものです。すべてのワーカー (ゴルーチン) は、他の人が終わるのを待たずに自分の仕事をこなします。

3. Redis による分散ストレージの最適化

分散レート リミッターには 共有状態 が必要です。ここで Redis が活躍します。しかし、Redis を接続してそれで終わりというわけにはいきません。最適化する必要がありました。

  • キーの有効期限ポリシー: Redis はレート制限されたクライアントごとにキーと値のペアを保存しますが、これらのキーの有効期限を効率的に設定することが重要でした。キーの有効期限が十分に早くないと、メモリが無駄になります。速すぎると、レート制限を見失います。 TTL (存続時間) を微調整して、メモリ効率と精度の間のスイートスポットを確実に満たすようにしました。
  • Redis レイテンシーの最小化: Redis はすでに高速ですが、負荷が高い場合は依然としてレイテンシーのスパイクが発生する可能性があります。 パイプラインレプリケーションの設定を調整することで最適化しました。これにより、データベースの遅延を制御しながら、1 秒あたりより多くのリクエストをプッシュできるようになります。

4.リクエストをバッチ処理してパフォーマンスを向上させる

スケールアップするために使用したもう 1 つのトリックは、リクエストのバッチ処理です。 ThrottleX は、すべてのリクエストを個別に処理するのではなく、バックグラウンドでまとめてバッチ処理します。これにより、Redis バックエンドにアクセスする操作の数が減り、ラウンド トリップが減り、スループットが高速化されます。

郵便で荷物を送るようなものだと考えてください。手紙ごとに郵便局に行く代わりに、束が揃うまで待って一度にすべて送るので、時間と労力を節約できます。


Go のパワーと最適化された Redis 構成に基づいて構築されたこのアーキテクチャにより、ThrottleX は大量のトラフィック負荷を効率的に処理できるようになりました。そして一番いいところは?すべて最小限の調整で拡張できるように設計されているため、数千または数百万のリクエストを処理するかどうかに関係なく、ThrottleX が対応します。


セクション 3: 100 万件のリクエストの秘密 – 主要な最適化

それでは、実際に ThrottleX をプッシュして、システムをクラッシュさせたりインフラストラクチャを破壊したりすることなく、1 秒あたり数百万のリクエスト を処理できるようにしたのでしょうか?結局のところ、レート制限アルゴリズムと基盤となるシステム アーキテクチャの両方において、一連の慎重に最適化が行われました。秘密のソースはこちらです:

1.高スループットのためのリクエストのバッチ処理

最大の変革要因の 1 つは、リクエストのバッチ処理でした。すべてのリクエストを個別に処理するのではなく、リクエストをバッチにグループ化しました。これにより、バックエンド (Redis) にアクセスする操作の数が大幅に減少し、ラウンドトリップが減少し、レイテンシーが短縮され、スループットが高速化されました。

言い換えると、通常は 10 件のリクエストを処理するのにかかる時間で 100 件のリクエストを処理するようなものです。この最適化だけで、ベンチマークのスループットが 50% 増加しました。

2.過負荷を防ぐサーキットブレーカー

この規模のトラフィックを処理していると、問題が発生する可能性があり、また問題が発生する可能性があります。トラフィック急増時に ThrottleX が圧倒されないようにするために、サーキット ブレーカー パターンを実装しました。

その仕組みは次のとおりです:

  • ダウンストリームのサービス (Redis やクライアント サービスなど) が遅れ始めたり、障害が発生したりすると、サーキット ブレーカーがトリップし、そのサービスへのリクエストが直ちに停止されます。
  • これにより過負荷が防止され、システムがクラッシュすることなく正常に回復できるようになります。
  • 問題が解決すると、ブレーカーが「リセット」され、交通が再び正常に流れます。

この設計は、システムに激しい負荷や一時的な障害が発生した場合でも、高可用性を維持するのに役立ちます。これがないと、Redis レプリケーションに遅れが生じたり、トラフィックが予期せず急増したりした場合に、ThrottleX が機能しなくなります。

3.メモリ効率 – ゴルーチンとプーリングの最適化

同時実行性は諸刃の剣です。 Go のゴルーチンは軽量ですが、それでもメモリ管理が必要です。規模を拡大するにつれて、ガベージ コレクション (GC) プロセスがボトルネックになり、特に高負荷下でパフォーマンスに悪影響を及ぼしました。

私たちの解決策は? リソースのプール:

  • 可能な限りゴルーチンを再利用して、メモリ フットプリントを削減し、GC オーバーヘッドを最小限に抑えました。
  • また、頻繁に使用されるデータ構造に対してカスタムのメモリ プールを実装し、一定のメモリ割り当てと割り当て解除を防ぎます。

結果は? メモリ使用量が 30% 削減し、トラフィック バースト時のパフォーマンスが大幅にスムーズになりました。

4. Redis パイプラインの最適化

Redis が大量のリクエスト負荷に確実に対応できるようにするために、パイプライン 機能を微調整しました。各コマンドを一度に 1 つずつ Redis に送信する (これにより遅延が発生します) 代わりに、複数のコマンドを 単一のリクエスト にバンドルしました。これにより、Redis はコマンドのバッチを並行して処理できるようになり、応答時間が大幅に短縮されました。

Redis パイプラインの魅力は、ネットワーク I/O を最小限に抑え、スループットを向上させる方法にあります。この最適化により、Redis は ミリ秒未満のレイテンシ で 1 秒あたり数百万のリクエストを処理できるようになりました。

5.適応型レート制限

適応型にすることで、レート制限を次のレベルに引き上げました。全体的に固定レートを使用する代わりに、ThrottleX はリアルタイムの交通状況に基づいてレート制限を動的に調整できます。

想像してみてください。通常のトラフィック中、システムは一貫したリクエスト フローを許可します。ただし、突然のスパイク (e コマース サイトのフラッシュ セールやアプリのバイラル モーメントなど) が発生した場合、ThrottleX は制限を一時的に緩和し、あまりにも積極的にスロットリングすることなく、より多くのトラフィックが通過できるようにします。スパイクが収まると、レートは自動的に元に戻ります。

この適応型アプローチにより、バックエンドを悪用から保護しながら、トラフィックの急増時に正当なユーザーが抑制されることがなくなります。

6.リアルタイムのメトリクスとモニタリング

私たちはレート制限を超えて、大規模に何が起こっているかを可視化したかったのです。これを行うために、リアルタイム監視PrometheusGrafana などのツールと統合しました。これにより、主要な指標を追跡できるようになりました。

  • リクエストのスループット (RPS – 1 秒あたりのリクエスト数)
  • エラー率
  • Redis レイテンシー
  • Goroutine の使用法

これらの洞察により、パフォーマンスのボトルネックを早期に発見し、問題になる前にシステムを微調整することができました。ダッシュボードにリアルタイムのトラフィックとシステムの健全性が表示されるため、ピーク負荷時でも ThrottleX のパフォーマンスを監視できます。


これらの最適化が連携することで、1 秒あたり 100 万リクエスト を処理できる機能が解放されました。バッチ処理やパイプライン処理からメモリの最適化や適応型レート制限に至るまで、それぞれの調整により、ThrottleX はハイパースケールの領域にさらに押し上げられました。 ?


セクション 4: 実際のベンチマーク – 証明するか負ける

本当のことを言いましょう。最適化について話すのは簡単ですが、証拠は常に数字にあります。一連のストレス テスト、ベンチマーク、微調整を経て、ThrottleX で達成した実際の指標を次に示します。

ベンチマークのセットアップ

次の構成を使用してテストを実行しました:

  • 環境: 5 つのノードを備えた分散システム セットアップ。各ノードは 16 GB の RAM を備えた 4 コア CPU で実行されます。
  • バックエンド: ノード全体で状態を共有するための Redis。パイプライン処理と最適化されたキー有効期限で微調整されます。
  • トラフィック負荷: 通常のトラフィック パターンとバースト トラフィック パターンの両方で、最大 1 秒あたり 100 万リクエスト をシミュレートしました。
  • ツール: モニタリング用の Prometheus とメトリクスのリアルタイム視覚化用の Grafana。

ここからは楽しい部分です。 結果は次のとおりです:

1.スループット – 1 秒あたり 100 万リクエスト

  • 1 秒あたりのリクエスト数 (RPS): 複数のノードにわたって 100 万 RPS を一貫して処理しました。
  • ピーク トラフィック: バースト シナリオ中、ThrottleX はパフォーマンスを大幅に低下させることなく、120 万 RPS までのトラフィック スパイクを処理しました。

ThrottleX は、低遅延と全体的なリソース消費を最小限に抑えながら、この負荷を処理しました。

2.レイテンシー – ミリ秒未満の応答時間

分散システムを扱う場合、特にこの規模ではレイテンシーが常に懸念されます。ただし、ThrottleX は、極端なトラフィック下でも一貫して ミリ秒未満の応答時間 を実現しました。

  • Redis の平均レイテンシー: 0.7 ミリ秒
  • 平均リクエスト遅延: 0.8 ミリ秒

Redis のパイプライン処理やリクエストのバッチ処理などの最適化のおかげで、データベースへの往復を最小限に抑え、レイテンシーを 1 ミリ秒未満に抑えることができました。

3.メモリ効率 – メモリ使用量が 30% 削減

ゴルーチンメモリ プーリングを最適化することで、従来のレート リミッタと比較してメモリ使用量の 30% 削減を達成しました。内訳は次のとおりです:

  • Goroutine Pooling: 数百万の同時リクエストを生成するオーバーヘッドを削減しました。
  • カスタム メモリ プール: トラフィック バースト時の割り当て数が大幅に減少し、パフォーマンスがより安定し、ガベージ コレクションの一時停止の頻度が減りました。

システム内を何百万ものリクエストが飛び交っていても、ThrottleX はメモリ効率を維持し、リソース消費を低く抑えました。

4.エラー率 – 0.001% 未満

システムがあちこちでエラーをスローする場合、大量のトラフィックを処理する意味はありませんか?幸いなことに、ThrottleX は盤石な信頼性を提供しました:

  • エラー率: ピーク負荷条件下であっても、失敗したリクエストまたは不必要にスロットルされたリクエストは 0.001% 未満です。

この信頼性は、システムの過負荷と連鎖的な障害の防止に役立つ適応レート制限サーキット ブレーカー パターンの有効性の証拠です。


これらのベンチマークは、机上で優れているだけではなく、現実世界のストレス テストによって裏付けられており、ThrottleX がパフォーマンスを損なうことなく極端なトラフィック負荷を処理できることを示しています。

そしてここが一番良いところです: 自分で試してみることができます! ?


自分で試してみる

これらのベンチマークに使用したすべてのコードと構成は、ThrottleX リポジトリ で入手できます。それをフォークして独自のテストを実行し、さらに進化できるかどうかを確認してください。このプロジェクトはオープンソースであり、コミュニティが何をもたらしてくれるかを見るのがいつも楽しみです。アルゴリズムの改善であっても、さらに高いスループットを実現するための最適化であっても、貢献やアイデアを歓迎します。

このサンプル アプリ、モニタリング コードへのリンク: https://github.com/neelp03/ThrottleX-Test

ThrottleX: Scaling to a Million Requests Per Second Without Breaking a Sweat


セクション 5: 学んだ教訓 – 私たちが驚いたこと

1 秒あたり 100 万リクエスト を処理できるものを構築するのは大変な作業であり、途中で貴重な教訓を学んだいくつかの予期せぬ課題に遭遇しました。私たちが最も驚いたことと、これらの障害にどのように取り組んだかについて説明します。

1. Go のガベージ コレクション – 静かなボトルネック

最初にスケールアップを開始したとき、トラフィックが多いときに応答時間がランダムに急増することに気づきました。この問題を詳しく調べた結果、Go の ガベージ コレクション (GC) が静かにパフォーマンスの問題を引き起こしていることがわかりました。

  • 問題: 何百万ものゴルーチンが飛び交っているため、GC が頻繁にトリガーされ、その結果、レイテンシーに影響を与える一時停止が発生していました。
  • 修正: カスタム メモリ プールを実装し、可能な場合はオブジェクトを再利用することで、メモリの割り当て方法を最適化しました。これにより、GC サイクルの頻度が減り、トラフィック急増時のパフォーマンスが平滑化されました。

教訓: Go のメモリ管理は効率的ですが、大規模な場合は、パフォーマンスのボトルネックを避けるためにメモリを細かく管理する必要があります。

2. Redis レプリケーションの遅延 – 隠された時限爆弾

Redis は高速ですが、1 秒あたり数百万のリクエストを処理する場合、レプリケーション ラグ が発生しました。トラフィックが多い状態では、ノード間でデータをレプリケートする Redis の機能が書き込み負荷に追いつくことができませんでした。

  • 問題: Redis レプリケーションの遅延により、マスター ノードとレプリカ ノード間のデータの同期に遅延が発生し、分散システム間でレート制限が一貫性を持たなくなりました。
  • 修正: 特定のシナリオでは一貫性よりも高可用性を優先するように、レプリケーションの頻度を減らし、Redis を微調整しました。これにより、時折古いデータが発生する代わりにパフォーマンスが向上しましたが、レート制限の場合、このトレードオフは許容範囲内でした。

学んだ教訓: Redis は猛獣ですが、大規模なスケールでは、パフォーマンスを高く保つために一貫性と可用性の間のトレードオフが必要になります。

3.ネットワーク遅延 – 目に見えない殺人者

分散ノード間でテストを行ったところ、ネットワーク遅延が、特にリクエストがリージョンを越えて送信される必要がある場合に急速に増加していることがわかりました。大規模な場合、数百万のリクエストに数ミリ秒の遅延が重なると、深刻なパフォーマンスの低下を引き起こす可能性があります。

  • 問題: 分散レート制限には、ノード間で Redis に戻る継続的な通信が含まれ、わずかなネットワーク遅延も加算されます。
  • 修正: レート制限ロジックを可能な限りローカライズし、Redis へのトリップ数を最小限に抑えることでシステムを最適化しました。最初にリクエストをローカルで処理し、状態を定期的にのみ同期することで、ネットワーク呼び出しへの全体的な依存関係を軽減しました。

学んだ教訓: ネットワーク呼び出しを最小限に抑えるは、分散システムにとって重要です。外部通信への依存が少なくなるほど、システムの回復力と速度が向上します。

4.適応型レート制限 – バランスを見つける

適応レート制限は状況を大きく変えるものでしたが、トラフィックの急増の許容と保護の維持との間のバランスを適切に保つことは、予想よりも困難でした。

  • 問題: 当初、レート制限が積極的に調整されすぎたため、スパイク時に過剰なトラフィックが許可され、一時的な過負荷が発生しました。
  • 修正: 長期的なトラフィック傾向を考慮してアルゴリズムを微調整し、時間の経過に伴うレート調整をスムーズにしました。これにより、交通量の急激な変動が防止され、持続的な交通量の急増時にシステムに余裕が与えられました。

学んだ教訓: 適応は強力ですが、過剰な修正を避けるために微調整する必要があります。調整が多すぎることは、調整が少なすぎることと同じくらい危険です。


ThrottleX の構築とスケーリングから、大規模なパフォーマンスは適切なバランスを見つけることがすべてです: メモリ使用量、ネットワーク遅延、レプリケーション、レート制限のバランスをとることがわかりました。すべての最適化にはトレードオフが伴いましたが、それぞれの課題により、より回復力があり、より高速なシステムを構築することが求められました。


結論 – あなたの番です: ThrottleX をさらに推し進める

ThrottleX は、極端なトラフィック負荷を処理できる、実績のある分散型レート リミッターです。しかし、さらに多くの余地が常にあります。新しい機能を提供したい場合でも、さまざまな条件でテストしたい場合でも、パフォーマンスをさらに向上させるために調整したい場合でも、ThrottleX リポジトリ はオープンしてお待ちしています。

一緒に限界を押し広げて、どこまでできるか試してみましょう。

以上がThrottleX: 苦労せずに 1 秒あたり 100 万件のリクエストに拡張の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。