当前位置:首页 > 问答 > 正文

限流 分布式系统 令牌桶算法在Redis中的实现与应用,令牌桶 redis

🚦 限流大作战:用Redis实现令牌桶算法,让系统稳如老狗!

场景引入
凌晨3点,你的电商系统突然被羊毛党狂刷优惠券接口,服务器CPU飙到99%… 😱 这时候如果有个「智能水龙头」,能控制流量忽大忽小,是不是很香?今天我们就用Redis手搓一个行业经典的令牌桶限流器


🔍 令牌桶是个啥?

想象一个水池(桶),系统以固定速率往里面丢令牌(Token),每个请求必须抢到令牌才能通行,没抢到的请求要么排队要么被拒。

限流 分布式系统 令牌桶算法在Redis中的实现与应用,令牌桶 redis

核心优势

  • 突发流量应对:桶里有存量令牌时,允许短时超额请求(比如秒杀开场)
  • 平滑限流:长期来看流量会被限制在恒定速率(比如1000次/秒)
  • Redis天然适配:原子操作 + 过期时间,完美契合分布式场景

🛠️ Redis实现四步走

📦 数据结构设计

用Hash存储桶状态,Key规则:rate_limit:{业务ID}

HSET rate_limit:coupon 
  tokens 100      # 当前令牌数
  last_time 1735660800  # 上次补充时间戳(2025-08示例)
  rate 10         # 每秒生成10个令牌
  capacity 200     # 桶最大容量

⏳ Lua脚本(原子操作核心)

local key = KEYS[1]
local now = tonumber(ARGV[1])
local tokens_requested = tonumber(ARGV[2])
local rate = tonumber(redis.call("HGET", key, "rate"))
local capacity = tonumber(redis.call("HGET", key, "capacity"))
local last_time = tonumber(redis.call("HGET", key, "last_time"))
-- 计算新增的令牌数(按时间差*速率)
local new_tokens = (now - last_time) * rate
local current_tokens = tonumber(redis.call("HGET", key, "tokens"))
current_tokens = math.min(current_tokens + new_tokens, capacity)  -- 不能超过桶容量
-- 判断是否允许请求
if current_tokens >= tokens_requested then
  redis.call("HSET", key, "tokens", current_tokens - tokens_requested)
  redis.call("HSET", key, "last_time", now)
  return 1  -- 成功
else
  return 0  -- 失败
end

🚀 调用示例(伪代码)

def is_allowed():
    timestamp = time.time()
    result = redis.eval(lua_script, 1, 
                       "rate_limit:coupon",
                       timestamp,
                       1)  # 每次消耗1个令牌
    return result == 1

⚠️ 增强版技巧

  1. 预热模式:系统启动时预填满令牌桶,避免冷启动被击穿
  2. 多级限流:针对不同用户等级设置不同桶容量(VIP用户桶更大)
  3. 监控告警:通过Redis的INFO KEYSPACE监控限流触发次数

🌟 真实应用场景

  1. API网关:保护下游服务,防止某个接口被刷爆
  2. 秒杀系统:前10秒允许高并发,后续进入平滑模式
  3. 爬虫控制:礼貌地限制对方爬取频率(反爬也要讲武德)

💡 避坑指南

  • 时钟回拨问题:服务器时间不准会导致令牌计算异常,建议用Redis的TIME命令获取时间
  • 分布式一致性:非极端场景下Redis已足够,若强一致可用RedLock(但性能下降)
  • 内存优化:对海量限流Key可设置TTL自动清理

:令牌桶就像个智能流量阀门🚪,而Redis的原子性和高性能让它成为分布式限流的黄金搭档,下次遇到流量暴增,不妨掏出这个方案,让你的系统稳如泰山!

限流 分布式系统 令牌桶算法在Redis中的实现与应用,令牌桶 redis

ℹ️ 本文技术点验证基于Redis 7.2+版本(2025-08环境)

发表评论