固定ウィンドウカウンターの仕組み
固定ウィンドウカウンターアルゴリズムの仕組み、その単純さ、トラフィックのバーストへの対応における潜在的な欠点を学びます。
「固定ウィンドウカウンターの仕組み」はCoddyKit上の無料API Rate Limiting & Scalability Patternsレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAPI Rate Limiting & Scalability Patterns学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 API Rate Limiting & Scalability Patternsコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
Why Algorithms?
Rate limiting isn't just a 'yes' or 'no' check. It relies on smart algorithms to manage traffic. These algorithms decide how and when to allow or deny requests, ensuring fairness and stability.
We'll start with one of the simplest: the Fixed Window Counter.
Fixed Window Counter: The Idea
The Fixed Window Counter is a straightforward rate limiting algorithm. It works by dividing time into fixed, non-overlapping windows.
- Each window has its own request counter.
- Once a request comes in, the counter for the current window increments.
- If the counter exceeds a predefined limit within that window, further requests are blocked.
How It Counts
Imagine a clock. For every minute (our fixed window), we allow, say, 10 requests. When a new minute starts, the counter resets to zero.
- Window: A specific time period (e.g., 60 seconds).
- Limit: Maximum requests allowed in that window.
- Counter: Tracks requests within the current window.
It's like a bouncer at a club, letting in only a set number of people each hour, then resetting the count for the next hour.
Example: 10 RPS Limit
Let's say our limit is 10 requests per second (RPS).
- Window 1 (0-1s): 7 requests made. 3 requests remaining.
- Window 2 (1-2s): 12 requests made. First 10 allowed, next 2 blocked.
- Window 3 (2-3s): 5 requests made. All allowed.
At the start of each new second, the counter resets, regardless of activity in the previous second.
Basic Counter Logic
Here's a simple Java class simulating a request counter. This forms the foundation of our rate limiter. It keeps track of requests within a defined window.
import java.time.Instant;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
class FixedWindowCounter {
private final int limit;
private final long windowSizeMillis; // e.g., 60_000 for 1 minute
private final ConcurrentHashMap<Long, AtomicInteger> counters;
public FixedWindowCounter(int limit, long windowSizeMillis) {
this.limit = limit;
this.windowSizeMillis = windowSizeMillis;
this.counters = new ConcurrentHashMap<>();
}
public boolean allowRequest(String userId) {
long currentWindowKey = Instant.now().toEpochMilli() / windowSizeMillis;
// Get or create counter for the current window
AtomicInteger counter = counters.computeIfAbsent(
currentWindowKey, k -> new AtomicInteger(0)
);
// Increment and check if within limit
return counter.incrementAndGet() <= limit;
}
}
public class Main {
public static void main(String[] args) {
System.out.println("FixedWindowCounter class defined.");
System.out.println("Ready to use in next example.");
}
}Testing the Window
Let's use our FixedWindowCounter class to simulate requests and see how it limits them within a 1-second window. Observe how requests are counted and then reset for the next window.
import java.time.Instant;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
// The FixedWindowCounter class
class FixedWindowCounter {
private final int limit;
private final long windowSizeMillis;
private final ConcurrentHashMap<Long, AtomicInteger> counters;
public FixedWindowCounter(int limit, long windowSizeMillis) {
this.limit = limit;
this.windowSizeMillis = windowSizeMillis;
this.counters = new ConcurrentHashMap<>();
}
public boolean allowRequest(String userId) {
long currentWindowKey = Instant.now().toEpochMilli() / windowSizeMillis;
AtomicInteger counter = counters.computeIfAbsent(
currentWindowKey, k -> new AtomicInteger(0)
);
return counter.incrementAndGet() <= limit;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
// Allow 3 requests per 1-second window
FixedWindowCounter limiter = new FixedWindowCounter(3, 1000);
System.out.println("--- First Window ---");
for (int i = 0; i < 5; i++) {
boolean allowed = limiter.allowRequest("user1");
System.out.println("Request " + (i + 1) + ": " + (allowed ? "ALLOWED" : "BLOCKED"));
}
// Wait for next window to start
Thread.sleep(1100);
System.out.println("\n--- Second Window ---");
for (int i = 0; i < 2; i++) {
boolean allowed = limiter.allowRequest("user1");
System.out.println("Request " + (i + 1) + ": " + (allowed ? "ALLOWED" : "BLOCKED"));
}
}
}Fixed Window: Pros
The Fixed Window Counter algorithm is popular for its simplicity and efficiency in certain scenarios.
- Easy to Implement: Requires minimal logic and data structures (just a counter and a timestamp).
- Low Resource Usage: Very little memory and CPU overhead per window.
- Predictable: The reset at the start of each window is clear and easy to understand.
It's a good choice for basic rate limiting where precision isn't paramount.
The Burst Problem
Despite its simplicity, the Fixed Window Counter has a significant drawback: it can allow twice the intended rate limit at the window boundaries.
Imagine a limit of 10 requests per minute.
- A user makes 10 requests at 0:59 (end of window 1).
- They then make 10 more requests at 1:01 (start of window 2).
This means 20 requests were made within a very short 2-minute period, effectively doubling the rate in a small burst.
Boundary Bursts
Let's visualize the burst issue with a 5 requests/minute limit.
- Window 1 (0:00 - 0:59): 5 requests sent at 0:58. (Allowed)
- Window 2 (1:00 - 1:59): 5 requests sent at 1:01. (Allowed)
In just 3 minutes (0:58 to 1:01), 10 requests were allowed. This is effectively 5 requests in ~3 seconds, not 5 requests per minute, defeating the purpose of the limit.
This 'burst' can overwhelm your system if not accounted for.
Fixed Window Check
Consider a fixed window rate limiter set to 5 requests per minute. The current time is 0:59:30. A user has already made 4 requests in the current window (0:00:00 to 0:59:59).
They then make another 3 requests at 0:59:45. Immediately after, at 1:00:05 (5 seconds into the next window), they make 3 more requests.
Recap: Fixed Window
We've explored the Fixed Window Counter algorithm:
- It divides time into distinct, non-overlapping windows.
- Each window has a request counter that resets at the start of a new window.
- It's simple to implement and understand.
- Its main drawback is the burst problem, where requests at window boundaries can effectively double the rate in a short period.
Next, we'll look at algorithms that try to smooth out these bursts!
よくある質問
「固定ウィンドウカウンターの仕組み」レッスンは無料ですか?
はい。「固定ウィンドウカウンターの仕組み」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、API Rate Limiting & Scalability Patternsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 API Rate Limiting & Scalability Patternsコースには全4レッスンが含まれています。
「固定ウィンドウカウンターの仕組み」で何を学びますか?
固定ウィンドウカウンターアルゴリズムの仕組み、その単純さ、トラフィックのバーストへの対応における潜在的な欠点を学びます。 ブラウザで直接実行するハンズオンコードでAPI Rate Limiting & Scalability Patternsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
API Rate Limiting & Scalability Patternsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAPI Rate Limiting & Scalability Patternsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「固定ウィンドウカウンターの仕組み」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAPI Rate Limiting & Scalability Patternsレッスンでコードを書いて実行できますか?
はい。すべてのAPI Rate Limiting & Scalability Patternsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 固定ウィンドウカウンターの仕組み
- リーキーバケットアルゴリズム詳解
- トークンバケットアルゴリズムの仕組み
- 適切なアルゴリズムの選択