レートリミッターとは何か?アルゴリズム、バジェット、スコープ
Scrapeless Web Unlocker は URL ベースのコンテンツ取得を処理し、アプリケーション側は許可するリクエストの周りにレートリミッターを配置できます。
TL;DR
- レートリミッターは、ポリシーに基づいて許可可否(アドミッション)の判断を行います。 そのスコープとカウント単位が、実際に何を保護している制限なのかを決定します。
- 異なるアルゴリズムは異なるバーストパターンを許容します。 同じ平均制限でも、ウィンドウ境界で異なるトラフィックを生み出すことがあります。
- 分散ワーカーには協調された会計処理が必要です。 ローカルカウンターを別々に持つだけでは、正確に 1 つのグローバル許容量を強制できません。
- リクエスト数だけでは、あらゆるリソースコストを制限することはできません。 必要に応じて、サイズ、複雑さ、同時実行数、支出管理などで高コストな処理を保護します。
レートリミッターはある操作への受付を制御する
レートリミッターとは、一定時間内の活動についてのポリシーに従い、ある操作を実行してよいかどうかを判断するコンポーネントです。これは、リクエスト送信前のクライアント側、API ゲートウェイ、あるいは高コストな処理の近くにあるアプリケーション内部に配置できます。このコンポーネントは適用対象の状態を観測してアドミッションの判断を行い、一方でポリシーは、誰のために何をどのようにカウントするかを定義します。
役に立つポリシーは、主体、操作、カウント単位、時間モデル、枯渇時のアクションを定義します。例えば、仮想的なエクスポートサービスは、テナントごとにエクスポート開始用の許容量を 1 つ、アクティブなエクスポート数に対する別の制限を割り当てるかもしれません。これは Scrapeless のクォータではなく、あくまで説明用の設計です。そうした詳細がないと、requests per minute のような表現は、負荷時に最も重要となる挙動を隠してしまうことがあります。
「 HTTP 429 definition 」は、過剰なリクエスト活動に対する HTTP サービス用のステータスを定義していますが、そのステータスは万能なリミッターアルゴリズムを規定しているわけではありません。サーバー側は、自身のポリシーに従って呼び出し元を識別し、操作をカウントできます。クライアントが 429 を観測しても、そのサービスが固定ウィンドウ、トークンバケット、あるいはより複雑なリソースバジェットを使っているかどうかを推測することはできません。
スコープは誰が許容量を共有するかを決める
リミッターのスコープは、どのリクエストが同じキャパシティを取り合うかを決定します。サービスは、アカウント、テナント、API キー、ユーザー、ルート、IP アドレス、もしくは複合キーごとに活動をカウントできます。IP ベースのポリシーは、共有ネットワークの背後にいる無関係なユーザーをまとめてしまう一方、アカウントベースのポリシーは、多数の異なるプロセスからのトラフィックをまとめます。保護したいリソースや公平性の境界に合うようにスコープを選択してください。
階層的なポリシーを同時に適用することもできます。あるリクエストは、テナントの許容量、エンドポイントの許容量、サービス全体の上限のいずれも満たす必要があるかもしれません。アドミッションシステムは、これらのチェックがどのように相互作用するか、および受理された作業がどのように計上されるかを定義しなければなりません。緩く寄せ集めただけの独立したチェック群では、不整合な控除が発生したり、本来は別の制約によって止められるべき作業を受け付けてしまうことがあります。
クライアントサイドアプリケーションにも同じスコープの意識が必要です。複数のコレクターが 1 つのプロバイダーアカウントを使用している場合、それぞれがフルの許容量を主張するのではなく、ディスパッチの判断はアカウントの割り当てを共有すべきです。ローカルリミッターは依然として 1 つのプロセスを保護できますが、その協調メカニズムが関係するすべてのコンシューマーを網羅していない限り、正確なグローバルポリシーとして説明すべきではありません。
固定ウィンドウとスライディングウィンドウは時間の数え方が異なる
固定ウィンドウリミッターは、名前の付いた時間区間内で許可された操作をカウントし、境界でカウントをリセットします。このアプローチは説明しやすく、運用コストも低く抑えられる場合があります。ただし境界での挙動が重要です。クライアントは、ある区間の終わり近くでその区間の許容量を使い切り、直後に次の区間の許容量をすぐに消費できます。そのため、個々の区間では低い平均値であっても、集中したバーストを含みうるのです。
スライディングログリミッターは、移動する時間区間内の活動のタイムスタンプを保持し、現在のウィンドウを直接評価します。より厳密なローリングポリシーを表現できますが、操作ごとのタイムスタンプを保存するには状態コストがかかります。スライディングウィンドウカウンターは、集約されたカウントでその挙動を近似します。その精度と境界での挙動は選択したアルゴリズムに依存するため、ポリシーが厳密か近似かを文書化してください。
これらの設計をテストするときは、区間境界での合成トラフィックを使用してください。一定ペースのワークロードだけでは、境界バーストや時計に起因する不整合が表面化しないことがあります。テストを実行する前に想定される受付数を定義し、エラーレスポンスの件数を数えるだけでなく、実際に許可された操作がポリシーと一致しているかを比較してください。リミッターの正しさは、定義済みモデルの下での意思決定履歴という性質です。
トークンバケットは持続レートとバーストキャパシティを分離する
トークンバケットは、時間とともに最大キャパシティまで貯まる許容量を維持します。許可された操作は、割り当てられたコストに応じてトークンを消費します。リフィルレートは継続的に許容される活動量を表し、バケットのキャパシティは蓄積された許容量をバーストとしてどの程度まで消費できるかを表します。これらは別々の設定であり、クライアントにも別々に説明されるべきです。
仮想的なバケットは、しばらく静かな期間の後に短時間のバーストを許可しつつ、長期的な活動は制約することができます。そのような挙動はインタラクティブなトラフィックには適していても、そのバーストを吸収できないバックエンドには不適切かもしれません。単に望ましい平均レートに合うという理由でデフォルト値をコピーするのではなく、サービスの実際の処理許容度からキャパシティを選択してください。
「 rate-limiting algorithm overview 」はトークンバケットとリーキーバケットの概念を説明しています。リーキーバケットという用語は、異なるポリシングまたはシェーピング設計を指すことがあるため、実装が過剰な操作を拒否するのか、それとも制御された排出レートで処理するためにキューに入れるのかを明示してください。2 つのライブラリが異なる運用挙動に同じ名前を使っている場合、実装名だけでは不十分です。
| 設計 | 有用な特性 | 文書化すべき境界 |
|---|---|---|
| 固定ウィンドウ | 単純な区間ベースの計数 | 隣接する区間全体にわたるバースト活動 |
| スライディングログ | 直接的なローリングウィンドウ履歴 | 1回の操作あたりの状態と処理コスト |
| スライディングカウンタ | 集約されたローリング近似 | 近似誤差と区間の重み付け |
| トークンバケット | 持続レートとバースト許容量の分離 | リフィルレート、容量、および操作コスト |
| キュー型シェーピング | 制御されたディスパッチ間隔 | キュー容量、待ち時間、有効期限 |
分散型アカウンティングにはアトミックな決定が必要
分散リミッターは、同時呼び出し元が同じ残り容量をすべて消費してしまわないように、チェックと更新を調整しなければなりません。カウンタを読み取り、後で更新する方式では、複数のワーカーが古い値を観測すると競合が生じます。状態ストアと一貫性要件に適したアトミック操作または別の調整メカニズムを使用してください。具体的な実装は、選択したインフラストラクチャに依存します。
調整にはコストも伴います。集中型の決定ポイントは、厳密なグローバル許容量を単純化できる一方で、ネットワーク遅延や依存関係を追加します。リージョンごとに独立した許容量を持たせると、調整を減らせますが、明確な配分とオーバーシュートのモデルが必要になります。設計が実際に提供する保証を明示してください。近似的な分散制御は有用ですが、裏付けとなる証拠なしに、正確なグローバル上限として売り込むべきではありません。
時間の扱いにも同様の明確さが必要です。ウィンドウ境界やリフィル計算に使う時間をどのコンポーネントが提供するか、状態がどのように失効するか、プロセスが再起動したときに何が起こるかを決めてください。テストでは、等間隔で呼び出しを行う 1 つのワーカーだけでなく、同時更新や状態ストアの変更もカバーする必要があります。単一プロセスのデモでは正しく見えるリミッターでも、フリート全体では異なる挙動を示す可能性があります。
レート、同時実行数、クオータ、および予算は別物である
レート制限は時間当たりの活動量を制限し、同時実行数制限は現在進行中の操作数を制限します。クオータは、より長期的な総量を制限でき、金銭的な予算は支出を制約できます。1 つのメカニズムが他のすべてを自動的に強制するわけではありません。処理が遅く高コストな操作を持つサービスは、リクエストレートの範囲内に収まっていても、メモリを使い果たしたり、アクティブな作業を溜め込みすぎたりする可能性があります。
リクエスト数もまた、作業量を測る指標の 1 つにすぎません。大きなエクスポートや複雑なクエリは、小さなルックアップよりも高コストになり得ます。 OWASP resource-consumption controls は、ペイロードサイズ、操作頻度、レコード数、サービス支出をカバーしています。リソースコストを HTTP リクエスト 1 件あたり 1 トークンでは十分に表現できない場合は、これらのコントロールを使用してください。
HTTP セマンティクスはさらに別の区別を加えます。受け付けられたリクエストが、常にビジネス操作の完了を意味するわけではありません。 HTTP response semantics は、メッセージの結果とアプリケーションの処理契約とを分離します。非同期エクスポートは受け付けられた後に、バリデーションや処理で失敗することがあります。各段階でどの予算を消費するのか、また有用な出力を生み出さなかった作業をアカウンティングがどのように表現するのかを決めてください。
枯渇と依存関係の障害には明示的なポリシーが必要
リミッターが枯渇した場合、呼び出し元と運用責任者の双方に対して明確な結果を示す必要があります。拒否、制限付きのキューイング、送信前の作業の取り下げは、それぞれ異なるプロダクト上の結果をもたらします。タスクの価値と期限に基づいて挙動を選択してください。無制限のキューはメモリを消費し、キャパシティが空いたときにはもはや意味をなさない作業をユーザーに待たせ続けることになります。
状態ストアが利用不能なリミッターには、明確な依存関係ポリシーが必要です。アカウンティングなしで作業を許可すると、上限を弱めながら可用性を守れます。一方、作業をブロックすると、予算を守りつつ有用なリクエストを拒否する可能性があります。操作の種類によって、必要な判断が異なる場合もあります。トレードオフを文書化し、ストレージライブラリの偶発的な挙動がポリシーになってしまわないように、制御された障害シナリオでテストしてください。
エラー報告では、認証情報や他テナントの活動を開示することなく、影響を受けたスコープを特定できなければなりません。ポリシー識別子、操作カテゴリ、および呼び出し元が対応可能なサニタイズ済みの理由を含めてください。運用担当者には、受付、拒否、キュー、および処理の集計メトリクスが必要です。高い拒否件数は、不正利用、不十分な配分、クライアントの不具合を示す可能性があり、それぞれ異なる対応が求められます。
公平性と有用な作業を観察する
優れたリミッターは、明示したポリシーを強制しつつ、有用な作業を保護します。誰がどれだけキャパシティを受け取っているか、受け付けられた作業がどれだけ待たされているか、高コストな操作が通常トラフィックを押しのけていないかを計測してください。先着順の配分では、各リクエストが個別には妥当であっても、1 テナントが共有許容量を使い切ってしまうことがあります。公平性がプロダクト要件であるなら、明示的な配分設計が必要です。
テスト用ワークロードには、バースト、不均一なテナント需要、低速な操作、大きな入力、ワーカーの同時起動を含めるべきです。これらのテストは、承認されたステージングまたはローカル環境で、合成データと制限されたボリュームで実行してください。目的は、意思決定モデルの検証であり、本番サービスを飽和させることでしきい値を探ることではありません。観測された受付結果を、想定したスコープと時間ポリシーと比較してください。
有用な運用レポートでは、受け付けられたリクエスト、完了した操作、保存されたレコード、および金銭的消費を区別して示します。これらの値は、正当な理由で異なり得ます。区別を維持することで、リミッターが実際のリソースを保護できているか、また配分が意図したプロダクト結果を生んでいるかをチームが把握できます。単一の成功率では、これらすべての境界を説明することはできません。
Scrapeless ワークフローの周囲にリミッターを配置する
クライアントは、 Scrapeless Web Unlockerへの呼び出しの周囲に受け付け制御を置くことができます。その場合でも、サービス自身のアカウント規則は独立して適用されたままです。 Web Unlocker overview URL に基づくコンテンツ取得について説明します。アプリケーションは対象スコープを選び、作業をキューに入れ、返されるコンテンツがデータセットの基準を満たしているかどうかを判断します。ローカルのリミッターは、対象ウェブサイトの許可ポリシーを変更することはできません。
レビュー Scrapeless の料金 サービスコストと関連する 同時実行性の概念 を参照してアクティブな作業を制御します。同じアカウントの割当を消費するコンシューマーには、共有の割当を 1 つ適用します。ネットワーク容量、財務的な余裕、およびデータ収集の許可は別個の制約であるため、ソースの認可された収集条件をサービス予算と並べて見えるように保ってください。
仮想的なレポートジョブは、制限された 1 日あたりの割当を予約し、アクティブなリクエスト数を上限し、レポート期間後には送信されなかった観測値を期限切れにできます。その完了レポートでは、受け入れられたレコードと、収集されないまま残ったスコープを識別する必要があります。そのような設計により、リミッターが実際のビジネス要件と結び付き、利用可能なキャパシティが需要より少ない場合でも、生成されるデータセットを評価しやすくなります。
結論
レートリミッターは、スコープ、時間モデル、アルゴリズム、および会計の一貫性に依存して動作が決まるアドミッションシステムです。保護する必要があるリソースからこれらの特性を選択し、制御されたトラフィックでその境界をテストしてください。レート制御を、アプリケーションが必要とするコストおよびアクティブ作業の制限と組み合わせ、許可されたリクエストが実際に生み出した有用な作業をレポートしましょう。
Web データワークフローを構築する
Web Unlocker を共有リクエスト割当の中で使用し、アクティブな作業、支出、および受け入れられたコンテンツを個別に制御します。
今すぐ登録して手に入れましょう $5 分の無料クレジット — クレジットカードは不要です.
$5 クレジットを請求する →FAQ
レートリミッターと同時実行リミッターは同じものですか?
レートリミッターと同時実行リミッターは、異なる量を制御します。レート制限は時間経過に伴う活動を制約し、同時実行制限はアクティブなオペレーションを制約します。高速なレスポンスが多数の開始を生む場合や、低速なレスポンスが同時作業を増やしすぎる場合、システムには両方が必要になることがあります。
常に最適なレート制限アルゴリズムはどれですか?
あらゆるサービスに対して常に最適なレート制限アルゴリズムは存在しません。必要なバースト挙動、精度、調整コスト、状態サイズ、公平性モデルから選択してください。ユーザーやオペレーターがポリシーで許可される内容を予測できるよう、その選択を文書化しましょう。
各ワーカーは自分自身のグローバルクォータを強制できますか?
ワーカーごとに独立したカウンターを持つだけでは、その割当と調整がスコープ全体をカバーしていない限り、正確に 1 つのグローバルクォータを強制することはできません。ローカル制限は有用なプロセス制御ですが、共有アカウントの割当には、共有の会計処理か、明示的に境界付けされたパーティショニング設計が必要です。
HTTP 429 でリミッターアルゴリズムは分かりますか?
HTTP 429 はリミッターアルゴリズムを示すものではありません。これは、そのサービスのポリシーの下でリクエスト活動が過剰であることを示します。ステータスコードから固定ウィンドウやトークンバケットを推測するのではなく、文書化されたカウントスコープとエラー契約を確認してください。
リクエストごとに 1 トークンで、すべての高コストなエンドポイントを保護できますか?
リクエストごとに 1 トークンとするだけでは、すべての高コストなエンドポイントを必ずしも保護できません。リクエストコストは、ペイロードサイズ、返されるレコード、処理の複雑さ、またはサードパーティ料金に依存することがあります。保護対象のリソースに対して、適切なコスト、同時実行、サイズ、および支出の制御を追加してください。