首页/数据/Redis 进阶速查/令牌桶限流:Hash 加时间差补桶
本包目录(421 条)
数据结构与选型42 条
持久化56 条主从与哨兵51 条Cluster 集群44 条内存与管理99 条性能与排障129 条

令牌桶限流:Hash 加时间差补桶

用 Hash 保存剩余令牌数与上次补充时间:每次请求按流逝时间补令牌、够则扣减放行;适合允许突发流量的场景。

Redis 进阶速查数据更新于 2026-10-12
结构字段 tokens 与 ts,速率 rate、桶容量 burst
补充tokens 取 burst 与 tokens 加 elapsed*rate 的较小值
判定令牌不少于 1 时放行并减 1

Lua 脚本示意

Lua 脚本示意
local rate = tonumber(ARGV[1])
local burst = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local t = redis.call('HMGET', KEYS[1], 'tokens', 'ts')
local tokens = tonumber(t[1]) or burst
local ts = tonumber(t[2]) or now
local delta = math.max(0, now - ts) / 1000
local filled = math.min(burst, tokens + delta * rate)
local allowed = 0
if filled >= 1 then
  filled = filled - 1
  allowed = 1
end
redis.call('HSET', KEYS[1], 'tokens', filled, 'ts', now)
redis.call('PEXPIRE', KEYS[1], math.ceil(burst / rate * 2000))
return allowed
与滑动窗口相比,令牌桶允许桶内突发(不超过 burst),长窗口平滑性略弱;两种都可用 Lua 在单次往返内完成。

易错点

  • 时间源用服务端时间更稳,客户端时钟漂移会算错补充量
  • 桶容量与速率需要压测校准,拍脑袋参数会在促销流量下失效

数据来源与参考

  • Redis 官方文档:EVAL 脚本模式;令牌桶算法通用说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌