首页/数据/数据库速查/滑动窗口与令牌桶限流(Lua 原子化)
本包目录(495 条)
MySQL 基础与连接36 条SQL 语法52 条用户与权限21 条备份与恢复56 条主从复制与高可用53 条性能与调优57 条Redis 命令96 条
Redis 运维与场景124 条

滑动窗口与令牌桶限流(Lua 原子化)

更平滑的限流:滑动窗口用 ZSet 存请求时间戳,令牌桶用 Hash 存令牌数与上次填充时间;判断与写入必须放进 Lua 一次原子完成。

数据库速查数据更新于 2026-10-12

滑动窗口 Lua

滑动窗口 Lua
-- KEYS[1]=限流键; ARGV: now_ms, window_ms, limit, 唯一请求ID
local now = tonumber(ARGV[1])
redis.call('ZREMRANGEBYSCORE', KEYS[1], 0, now - tonumber(ARGV[2]))
if redis.call('ZCARD', KEYS[1]) >= tonumber(ARGV[3]) then return 0 end
redis.call('ZADD', KEYS[1], now, ARGV[4])
redis.call('PEXPIRE', KEYS[1], ARGV[2])
return 1
滑动窗口ZSet 成员=请求(近似精确),内存随请求量增长
令牌桶Hash(tokens,ts) + 速率参数,允许突发
调用EVAL 脚本 1 键 now window limit 请求ID
唯一ID请求ID 保证同毫秒多请求不覆盖(如 uuid)
高 QPS 下 ZSet 窗口每个请求一个成员,内存开销大;大流量常用「固定窗口+令牌桶」组合或网关侧限流。

易错点

  • GET/SET 分步实现:并发下超限(必须单命令或 Lua)
  • 客户端时间不单调/回拨:窗口判断失真,尽量用服务端 TIME 或强制单调时钟

数据来源与参考

  • Redis 官方文档: EVAL
  • 限流模式实践(令牌桶/滑动窗口)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌