Master Redis Rate Limiting: SetNX, ZSet Sliding Window, and Token Bucket
This article explains three practical Redis-based rate‑limiting techniques—using SETNX for simple counters, ZSET for a sliding‑window algorithm, and a token‑bucket implementation with List—complete with Java code examples and discussion of their advantages and drawbacks.
First Method: Using Redis SETNX
Redis' distributed lock relies on the SETNX command combined with an expiration time. By setting a key with SETNX and an expire of, for example, 10 seconds, you can limit the number of requests within that interval; when the count reaches the limit, further requests are blocked. This approach is simple but cannot handle sliding windows (e.g., counting requests from 2‑11 seconds when the fixed window is 1‑10 seconds).
Second Method: Using Redis ZSET
The sliding‑window problem can be solved with Redis' sorted set (ZSET). Each request is added as a member with a unique value (e.g., a UUID) and a score equal to the current timestamp. By querying the range of scores within the desired time interval, you can count how many requests occurred. The following code demonstrates this approach:
public Response limitFlow() {
Long currentTime = new Date().getTime();
System.out.println(currentTime);
if (redisTemplate.hasKey("limit")) {
Integer count = redisTemplate.opsForZSet()
.rangeByScore("limit", currentTime - intervalTime, currentTime)
.size(); // intervalTime is the rate‑limit period
System.out.println(count);
if (count != null && count > 5) {
return Response.ok("每分钟最多只能访问5次");
}
}
redisTemplate.opsForZSet().add("limit", UUID.randomUUID().toString(), currentTime);
return Response.ok("访问成功");
}This implementation provides a sliding‑window effect, ensuring at most M requests per N seconds, but the ZSET size grows over time.
Third Method: Token Bucket with Redis List
The token‑bucket algorithm controls flow by maintaining a pool of tokens. Each request attempts to pop a token from a Redis list; if a token is obtained, the request proceeds, otherwise it is rejected. Tokens are replenished periodically using a scheduled task that pushes unique identifiers (UUIDs) onto the list.
public Response limitFlow2(Long id) {
Object result = redisTemplate.opsForList().leftPop("limit_list");
if (result == null) {
return Response.ok("当前令牌桶中无令牌");
}
return Response.ok(articleDescription2);
} @Scheduled(fixedDelay = 10_000, initialDelay = 0)
public void setIntervalTimeTask() {
redisTemplate.opsForList().rightPush("limit_list", UUID.randomUUID().toString());
}By integrating any of these snippets into an AOP interceptor or servlet filter, you can protect your APIs from excessive traffic.
Beyond rate limiting, Redis offers many other data structures and features such as GeoHash, BitMap, HyperLogLog, and Bloom filters (available from Redis 4.0 onward), which are worth exploring for advanced use cases.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
