仕組み
レート制限は、一定の条件で受け入れるリクエスト数を制限します。
目的には、サーバー保護、利用者間の資源配分、契約プランごとの制御などがあります。
固定ウィンドウ方式
「時計上の1分ごとに100件まで」のように、区切った時間枠で数えます。
12:00:59 に100件 → 許可
12:01:00 に100件 → 新しい枠なので許可
各分の上限は守っていますが、境界付近に200件が集中します。
実装が単純な一方、時間枠の境界で急増を許すという特徴があります。
トークンバケット方式
仮想的なバケツに、リクエストを許可するためのトークンを貯めます。
例として、次の設定を考えます。
バケツ容量:20トークン
補充速度 :毎秒5トークン
1リクエストで1トークン消費
満杯なら20件の一時的な集中を受け入れられます。使い切った後は、補充される速度に応じて処理を許可します。
つまり、次の2つを分けて設定できます。
- 容量:一時的な集中をどれだけ許すか。
- 補充速度:継続的な利用をどれだけ許すか。
固定ウィンドウやトークンバケットの動作は、Microsoftの実装資料でも説明されています。Microsoft:レート制限アルゴリズム
「公平性」はアルゴリズムだけでは決まらない
全利用者で1個のバケツを共有すると、特定の利用者が使い切る可能性があります。
利用者間の公平性を考えるなら、たとえば次のような分割が必要です。
利用者ごとの上限
+
組織ごとの上限
+
システム全体の上限
また、軽い検索1回と重い帳票生成1回を同じコストとして扱うと、件数だけでは負荷を制御できません。
使い分けと注意点
トークンバケットは、一時的な集中を許しながら継続レートを制御する用途に向いています。一方、「どの連続60秒間でも必ず100件以下」のような要件には、別の方式を検討する必要があります。
制限時には通常 429 Too Many Requests を返し、再試行可能な時刻を案内できるなら Retry-After を付けます。AWS API Gatewayもトークンバケットを用い、制限時の429を説明しています。AWS:APIのスロットリング
設計上の要点
「誰に」「何の単位で」「どの程度の集中まで」許すかを先に決めます。