+ 作るログイン
図を読み込んでいます…
1 / 7
動きでわかる Webとデータの仕組み / 全10章

トークンバケット:一瞬の集中と、長く続く流量

発行
アニメモ公式
版
第1版
改訂
コマ
全7

容量3・毎秒1個補充のバケットで、瞬間的な集中、枯渇、時間経過、満杯を追い、レートと同時実行数の違いを知る。

ためられる量と、増える速さは別

トークンバケットを、APIへのリクエストを通すためのモデルとして使います。容量Bは3、補充速度rは毎秒1個。最初は満杯で、一件を通すたびに一つ消費するものとします。

容量は短時間の集中を受け止める余裕、補充速度は長く続く流量に関わります。トークンは概念上の残高で、実装で毎秒タイマーを動かして物体を追加する必要はありません。

これは説明用の厳密なモデルです。実サービスの制限が同じ精度で適用されるとは限らず、AWS API Gatewayなどはベストエフォートの目標として説明しています。API Gateway:スロットリング

  • 10 / WEB SYSTEMS
  • 1 / 7
  • 三つためられて、一秒に一つ補充される
  • t = 0 秒
  • 補充 r = 1 / 秒
  • 容量 B = 3
  • 一件通すと、一つ消費
  • 1
  • 1
  • 1
  • リクエストが来る
  • 容量は一度に通せる集中、補充速度は長期の流量に関わる。

満杯なら、一瞬に3件を通せる

t=0秒に三件が到着します。各リクエストが一つずつ使い、残数は3、2、1、0と減ります。図では説明のため、補充が起こるほどの時間差はないとしています。

補充速度が毎秒1個でも、既に三つためてあったので三件を通せます。「毎秒1件」という言葉だけでは、この瞬間的な許容量は分かりません。

このモデルは「どんな一秒区間でも、必ず一件以下にする」という制限とは異なります。バケットの容量と補充速度をセットで読みます。

  • 10 / WEB SYSTEMS
  • 2 / 7
  • 同じ時刻の3件で、三つを使い切る
  • t = 0 秒
  • 補充 r = 1 / 秒
  • 容量 B = 3
  • 一件通すと、一つ消費
  • 通過1
  • 通過2
  • 通過3
  • 残り 0 個
  • 毎秒1個でも、満杯からなら一度に3件通せる。

4件目には、使えるトークンがない

同じ時刻に四件目が来ても、残数は0です。この作品ではキューで待たせるのではなく、そのリクエストを拒否する方式を考えます。

HTTP APIなら 429 Too Many Requests で伝える方法があります。応答にRetry-Afterを付けることもできますが、常に付くとは限りません。利用側はサービスの指示に従い、再試行の間隔も考えます。

「通らなかったら間を空けずに連打する」だけでは、混雑を増やします。RFC 6585:429

  • 10 / WEB SYSTEMS
  • 3 / 7
  • 同じ時刻の4件目は、トークンが足りない
  • t = 0 秒
  • 補充 r = 1 / 秒
  • 容量 B = 3
  • 一件通すと、一つ消費
  • 4件目:通せない
  • この例は待たせず拒否する方式。APIなら429などで伝える。

二秒の経過で、二つ使えるようになる

追加のリクエストがないまま2秒が経過しました。補充速度が毎秒1個なので、残数は2です。そこへ次の一件が到着します。

一般的には、最後の評価時刻と残数を記録し、経過時間に速度を掛けて補充量を計算できます。時刻の進み方や小数の扱いは実装で決めます。

一定時刻に全利用者の枠を一斉に初期化する固定窓の図ではありません。前の状態から、時間の経過で残高が増えると追ってください。

  • 10 / WEB SYSTEMS
  • 4 / 7
  • 2秒待つと、二つ補充される
  • t = 2 秒
  • 補充 r = 1 / 秒
  • 容量 B = 3
  • 一件通すと、一つ消費
  • 1
  • 1
  • 次の1件が到着
  • 0 + 1 × 2 = 2 個
  • 補充は時間の経過による。利用者ごとに窓が一斉リセットしない。

一件を通したら、残数は一つ

残数2から一つを消費し、残りは1になりました。残数が足りるか確かめることと、消費を記録することを原子的に行わないと、同時の二つの処理が同じ最後の一つを使えてしまいます。

制限を複数のサーバー全体で共有するなら、共有状態や調整の仕組みも必要です。各サーバーが独立した同じ大きさのバケットを持つだけでは、全体の同じ上限にはなりません。

利用者、APIキー、テナント、IPなど、どのキーで分けるかも設計です。例えばIP単位では、同じネットワークを共有する利用者が一緒の枠になることがあります。

  • 10 / WEB SYSTEMS
  • 5 / 7
  • 一件を通し、残り一つになる
  • t = 2 秒
  • 補充 r = 1 / 秒
  • 容量 B = 3
  • 一件通すと、一つ消費
  • 1
  • 次の1件が通過
  • 2 − 1 = 1 個
  • 残数を調べることと消費することは、原子的に行う。

長く使わなくても、三つより多くはたまらない

t=2秒で残数1のまま、その後10秒使わなかったとします。計算上は11になりますが、容量3で頭打ちになるため、t=12秒の残数は3です。

補充後の残数 = min(B, 前の残数 + r × 経過時間)

十分な残数があれば、ここからそのリクエストの消費量を引きます。長い時間待った利用者が、無限に大きい瞬間負荷をため込めるモデルではありません。

容量と速度を分けることで、短い集中には余裕を持たせながら、続く流量は抑えられます。

  • 10 / WEB SYSTEMS
  • 6 / 7
  • 長く待っても、容量を超えてはたまらない
  • t = 12 秒
  • 補充 r = 1 / 秒
  • 容量 B = 3
  • 一件通すと、一つ消費
  • 1
  • 1
  • 1
  • 10秒待っても満杯は3
  • min(3, 1 + 1 × 10) = 3
  • 新しい残数 = min(容量, 残数 + 速度 × 経過時間)。

毎秒1個なら、一瞬にも1件しか通せない?

答えはいいえです。容量3で満杯なら、同じ時刻の三件を通せます。一方、枯渇した後に長く続けて通せる量は、補充速度に制約されます。

さらに、流量と同時実行数は別です。毎秒一件でも、一件の処理が100秒続けば、処理中の仕事は積み上がり得ます。実行中の数を抑えるには、別の同時実行制限などを検討します。

トークンをためる箱、時間による補充、処理中の仕事。この三つを別々に描くと、「何を制限して守りたいのか」が具体的になります。

  • 10 / WEB SYSTEMS
  • 7 / 7
  • 確認:毎秒1件なら、一瞬に通せるのも1件?
  • 容量 B
  • 補充速度 r
  • 同時実行数
  • 一時的な集中を許す余裕
  • 継続して通せる流量
  • 処理中の数を別に制御
  • 流量と、処理中の数は別の量
  • 答えは NO。容量3なら3件の集中を許せる。

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]