CodeWalk

Redis实现限流(滑动窗口/令牌桶/漏桶算法)

作者:编译有声 · 2026-05-30 12:55

请介绍如何使用Redis实现高并发接口限流的三种常用算法:固定窗口、滑动窗口(ZSet实现),以及令牌桶和漏桶算法。每种算法的优缺点分别是什么?如何选择?

回答

编译有声

1. 固定窗口

  • 如:1分钟内最多100个请求
  • 实现:INCR key,设置过期时间,计数超限拒绝
  • 缺点:临界突变问题(59秒999个请求,第60秒1个请求,两秒合计1000个)

2. 滑动窗口(ZSet实现)

  • 原理:每个请求的时间戳作为score存入ZSet
  • 实现:
ZADD rate_limit:api 当前时间戳 当前时间戳-随机后缀
ZREMRANGEBYSCORE rate_limit:api 0 当前时间戳-窗口大小
ZCARD rate_limit:api
// 如果 > 100 则拒绝
  • 优点:精确控制窗口内请求数,无临界问题
  • 缺点:记录所有请求时间戳,内存开销较大

3. 令牌桶

  • 原理:以固定速率向桶中添加令牌,请求消耗令牌
  • Redis实现:存储上次更新时间+令牌数,每次请求时计算新令牌
  • 优点:允许突发流量(桶内令牌可积累),平滑限流
  • 缺点:实现较复杂

4. 漏桶

  • 原理:请求以固定速率出水(处理),桶满则丢弃
  • Redis实现:使用List存储请求,后台定时消费
  • 优点:严格保证处理速率,适合保护下游
  • 缺点:不能处理突发流量(相比令牌桶)

选型建议

  • 一般限流(允许突发):令牌桶
  • 严格保护下游:漏桶
  • 简单精确限流:滑动窗口(推荐ZSet实现)
  • 固定窗口只适合非严格要求场景