「レート制限について知るべきこと」
「美容とファッションのエキスパートが語る、レート制限に関する重要な情報」
レート制限は、送信されるトラフィックの量を制御する概念です。この制御をどのように実現できるのでしょうか?それはレートリミッターによって行います- ネットワークトラフィックのレートを制御するコンポーネントであり、APIサーバーや他の保護したいアプリケーションへのトラフィックのレートを制御することができます。
以下は、レートリミッターがシステムのコンテキストにどのように配置されるかを示す大局的な見方です。
たとえば、クライアントがサーバーに3つのリクエストを送信するが、サーバーは2つのリクエストだけを処理できる場合、レートリミッターを使用して余分なリクエストがサーバーに到達しないように制限することができます。
レート制限の必要性
システムにレート制限を導入する強力な理由のいくつかは以下のとおりです:
- 悪意のある者によるシステムの乱用を防止する。異常な数のリクエストでサーバーを圧倒しようとする攻撃者を防ぎます。
- 実際にサーバーが処理できるトラフィックのみを許可するために。
- 外部システムからの高価なリソースの消費を制限するために。
- 多数のリクエストによってトップレベルのシステムが崩壊した場合、下位システムでのカスケード障害を防ぐために。
レート制限の基本概念
どの種類のレート制限アルゴリズムを採用しても、共有される3つのキーとなる概念が存在します。
それぞれについて簡単に見てみましょう。
- 制限 — システムが特定の時間枠で許可される最大リクエスト数を定義します。たとえば、Twitter(現在のX)では最近、未確認のユーザーは1日につき600件のツイートのみを閲覧できるようにレート制限されました。
- ウィンドウ —これは制限の時間枠です。秒から分、そして日数まで様々な長さのウィンドウを持つことができます。
- 識別子 —それは個々のリクエスト所有者を区別するための一意の属性です。たとえば、ユーザーIDやIPアドレスなどが識別子の役割を果たすことができます。
レート制限を備えたシステムの設計
レートリミッターの基本的な原則は非常にシンプルです。高いレベルでは、特定のユーザーまたはIPアドレス、あるいは地理的な場所から送信されるリクエストの数を数えます。カウントが許容制限を超えた場合、リクエストを許可しません。
ただし、裏側では、レートリミッターの設計時に考慮する必要がある点がいくつかあります。例えば:
- カウンタをどこに保存すべきですか?
- レート制限のルールについてはどうですか?
- 許可されていないリクエストへの応答方法は?
- ルールの変更が適用されることをどのように保証しますか?
- レート制限がアプリケーション全体のパフォーマンスを低下させないようにするためにはどうすればよいですか?
これらすべての考慮事項をバランスさせるためには、相互に連携する複数の要素が必要です。以下は、そのようなシステムを描いた図です。
ここで何が行われているか理解しましょう:
- リクエストがAPIサーバーに到着すると、まずレートリミッターコンポーネントに到達します。レートリミッターはルールエンジンのルールをチェックします。
- レートリミッターはキャッシュに格納されたレート制限データをチェックします。このデータは、特定のユーザーまたはIPアドレスに対して既に提供されたリクエストの数を示しています。キャッシュを使用する理由は高いスループットを実現するためです。
- もしリクエストが許容範囲内であれば、レートリミッターはAPIサーバーにリクエストを送信します。
- リクエストが制限を超える場合、レートリミッターはリクエストを拒否し、クライアントまたはユーザーにレート制限がかかったことを通知します。一般的な方法は、HTTPステータスコード429(リクエストが多すぎる)を返すことです。
改善の可能性
ここで続けていくつかの改善策があります:
- まず、HTTPステータスコード429を返す代わりに、リクエストを静かにドロップすることもできます。これは、レートリミッターが実際にはリクエストを完全にドロップしているにもかかわらず、攻撃者を騙す有用なトリックです。
- 次に、パフォーマンスを向上させるためにルールエンジンの前にキャッシュを配置することもできます。ルールの更新がある場合には、バックグラウンドのワーカープロセスがキャッシュを最新のルールセットで更新することができます。
レート制限アルゴリズム
各アルゴリズムについて詳しく議論する必要がありますが、ここでは最も人気のあるアルゴリズムについて簡単に見ていきます。
フィックスウィンドウカウンター
これはおそらく存在する最もシンプルなレート制限アルゴリズムです。このアルゴリズムでは、時間を固定の時間ウィンドウに分割します。各ウィンドウごとに、カウンターを維持します。すべての入力リクエストは、カウンターを1増やし、カウンターが最大制限に達すると、次のリクエストは新しい時間ウィンドウが開始されるまで破棄されます。
このアルゴリズムはシンプルで理解しやすいですが、大きな問題があります。時間ウィンドウの端でのトラフィックの急増により、短時間で大量のリクエストが通過し、サーバーが圧倒されることがあります。
興味があれば、フィックスウィンドウレート制限アルゴリズムの基本的な実装をご覧ください。
スライディングウィンドウログ
スライディングウィンドウログはフィックスウィンドウアルゴリズムの問題を解決します。固定の時間ウィンドウではなく、スライディングの時間ウィンドウを保持します。
各リクエストでは、アルゴリズムはキャッシュ内のリクエストのタイムスタンプを追跡します。新しいリクエストが到着すると、現在の時間ウィンドウの開始よりも古いタイムスタンプはすべて削除されます。ログのサイズが許容制限内であれば、リクエストは受け入れられます。そうでなければ、リクエストは拒否されます。
もちろん、このアルゴリズムはすべてのタイムスタンプを追跡するため、多くのメモリを消費するという問題があります。
スライディングウィンドウカウンター
スライディングウィンドウカウンターはフィックスウィンドウとスライディングウィンドウの最良の部分を組み合わせます。
このアルゴリズムでは、タイムスタンプではなく、スライディングウィンドウのためのカウンターを維持します。新しいリクエストを受け入れるかドロップするかを判断するために、現在のウィンドウでのリクエストの合計を計算し、以前のウィンドウのリクエストの近似値に加えます。以前のウィンドウでのリクエストの近似値は、スライディングウィンドウのオーバーラップパーセンテージによって以前のウィンドウでのリクエストの総数に乗算することで計算されます。
このアルゴリズムの利点は、トラフィックのスパイクを平滑化し、メモリ効率が高いことです。ただし、正確なリクエストの数を計算せず、近似値で処理する点に注意が必要です。
トークンバケット
トークンバケットアルゴリズムは、レート制限に非常に人気のあるアルゴリズムです。
このアルゴリズムでは、事前に定義された容量を持つトークンのバケットを作成します。トークンは事前に設定された速度でバケットに配置されます。バケットがいっぱいになると、トークンは追加されません。新しいリクエストが来ると、トークンが消費されます。バケット内に利用可能なトークンがない場合、レート制限はリクエストをドロップします。
このアプローチの利点は、一時的なバーストトラフィックを短時間通過させることができる点です。
主な課題は、バケットサイズとトークンの補充速度の組み合わせを調整することです。
リーキングバケット
リーキングバケットアルゴリズムは、トークンバケットと非常に似ています。唯一の違いは、リクエストが一定の速度で処理されることです。
これはFIFOアプローチで実装されています。リクエストが到着すると、システムはキューがいっぱいかどうかをチェックします。いっぱいでない場合、リクエストはキューに追加されます。それ以外の場合は、リクエストは破棄されます。
キュー内のリクエストは、サーバーが圧倒されるのを避けるために一定の速度で処理されます。
レート制限のユースケース
レート制限は外部からのリクエストからシステムを保護するために使用されると考えるのが簡単かもしれませんが、内部でも役立つ場合があります。
このイントロダクションポストを終わる前に、レート制限の外部および内部のユースケースをいくつか見てみましょう。
- 壊滅的なDDoS攻撃を防ぐ—これは、システムを圧倒しようとする悪意のあるIPアドレス、ユーザー、またはリクエストトークンを特定することによって行われます。アルゴリズムに応じてリクエストが破棄されます。
- ユーザーの急増に優雅に対応する—すべてのトラフィックが悪意のあるわけではありませんし、ウェブサイトが正当なトラフィックの急増を引き付けることもあります。ただし、増加したトラフィックを処理する能力がない場合、ユーザーに失敗画面を表示するのではなく、優雅に処理することがより良いです。
- 多層価格設定—これは内部のユースケースで、異なるティアに属するユーザーに異なる利用レベルを提供したい場合です。これは、多くのオンデマンドSaaSサービスにおいて一般的な要件です。
- サードパーティシステムの過度な使用を防ぐ—これは、高価なサードパーティAPI(例:ディープラーニングモデル)へのAPI呼び出しの数を制限したい場合の別の内部のユースケースです。レート制限を使用して呼び出しの数を制限できます。
- 保護されていないシステムを保護する—時には、無防備なシステムに慎重に対処したい場合があります。たとえば、データベースから100万件のレコードをハードデリートする場合、一度に操作を行うとデータベースをダウンさせるリスクがあります。レート制限のアルゴリズムを利用して削除を均等に分散することができます。
結論
レート制限は、高い可用性を持つシステムを構築するための重要なツールです。この記事では、レート制限の全体像とそれがなぜ必要なのかについてのみ触れました。本記事で言及されたアルゴリズムは、それぞれ独自の理論的な基礎と実践的な考慮事項を持っています。
ご質問やコメントがある場合は、以下のコメント欄にお気軽にお書きください。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles