670 字
3 分钟
Redis 如何实现限流?固定窗口和滑动窗口怎么选?
  1. 1Redis 系列导读:知识地图、必会主线与复习顺序
  2. 2Redis 中常见的数据类型有哪些?
  3. 3Redis 通常应用于哪些场景?
  4. 4Redis为什么这么快?
  5. 5Redis 常用的过期时间、删除 Key 命令有哪些?
  6. 6Redis 的过期 Key 是如何被删除的?
  7. 7Redis 内存满了怎么办?有哪些淘汰策略?
  8. 8缓存穿透、击穿、雪崩的区别与解决方案
  9. 9Redis 如何保证缓存与数据库的数据一致性?
  10. 10Redis 的持久化机制有哪些?
  11. 11Redis 主从复制的完整流程是什么?
  12. 12Redis 的哨兵机制是什么?
  13. 13Redis Cluster 模式与 Sentinel 模式的区别是什么?
  14. 14Redis 支持事务吗?如何实现?
  15. 15Redis 中如何实现分布式锁?
  16. 16Redis 的 Lua 脚本功能是什么?如何使用?
  17. 17如何解决 Redis 中的热点 Key 问题?
  18. 18Redis BigKey 有什么危害?如何发现和治理?
  19. 19为什么 Redis 设计为单线程?6.0 版本为何引入多线程?
  20. 20Redis 的 LRU 和 LFU 有什么区别?
  21. 21Redis 数据类型和底层编码有什么区别?
  22. 22Redis 中跳表的实现原理是什么?
  23. 23Redis 的 ZSet 为什么使用跳表,而不是平衡树?
  24. 24Redis 的 RDB 快照如何生成?为什么会有写时复制?
  25. 25Redis 的 AOF 刷盘和重写有什么区别?
  26. 26Redis 断线后如何通过 PSYNC 部分重同步?
  27. 27Redis 主从切换为什么会丢数据?WAIT 能解决吗?
  28. 28Redis 集群会出现脑裂问题吗?
  29. 29Redisson 看门狗(watch dog)机制了解吗?
  30. 30Redis Cluster:哈希槽、Gossip 与故障转移
  31. 31Redis Pipeline 为什么能提高吞吐?能保证原子性吗?
  32. 32Redis 的 SCAN 和 KEYS 有什么区别?
  33. 33Redis 变慢时如何排查?SLOWLOG 能看到所有耗时吗?
  34. 34Redis 和 MySQL 有什么区别?
  35. 35Redis 为什么使用 SDS,而不是 C 字符串?
  36. 36Redis 的哈希表如何处理冲突和渐进式 rehash?
  37. 37Redis Cluster 的 MOVED 和 ASK 重定向有什么区别?
  38. 38Redis Cluster 为什么会报 CROSSSLOT?Hash Tag 怎么用?
  39. 39Redis 如何实现限流?固定窗口和滑动窗口怎么选?本文
  40. 40Redis Stream 如何保证消息消费?ACK 和 PEL 是什么?
  41. 41Redis 删除数据后为什么内存不下降?如何理解内存碎片?

Redis 限流的核心是保存共享的配额状态,并原子地判断、更新和设置生命周期。固定窗口计数简单,滑动窗口更平滑,令牌桶能允许受控突发;没有一种方案适合所有接口。

固定窗口有什么边界?#

按用户和分钟构造 Key,对它 INCR,首次计数时设置 TTL,超过阈值拒绝。若 INCR 成功但客户端在 EXPIRE 前退出,Key 可能不再过期。因此不能仅把两个命令连续调用就认为整体可靠,可用简短 Lua 完成组合。

每分钟最多 100 次的固定窗口,在 12:00:59 发 100 次,再在 12:01:00 发 100 次,短时间仍可能出现 200 次请求。这是窗口边界突发,不是 INCR 不原子。

滑动窗口与令牌桶#

ZSet 滑动窗口可以用时间戳作分数、唯一请求标识作成员。在一个原子操作中删除窗口之前的记录,统计剩余数量,未达上限时加入新记录并设置过期时间。成员必须唯一,否则同一毫秒的多个请求可能互相覆盖,导致少计数。其内存与每用户窗口内请求数有关,超高吞吐场景要控制粒度或使用近似窗口。

令牌桶保存当前令牌数和更新时间,按流速补充至容量上限,请求消耗令牌;桶容量决定可允许的突发,补充速率决定长期速率。不要每毫秒真实往 Redis 写一次“增加令牌”,可在请求到来时按时间差计算补充。

常见追问#

为什么这里通常用 Lua?#

读配额、判断、增加计数和 TTL 设置需要作为一个组合操作完成,避免并发检查都通过。脚本应短小,不能长时间阻塞实例。

Redis 故障时放行还是拒绝?#

按业务风险决定。公共查询可能降级到本地限流,支付或高风险操作可能限制放行;要明确降级策略,避免故障直接放大数据库流量。

所有用户共用一个限流 Key 好吗?#

全局 Key 可以保护总容量,但会成为热点且无法提供用户公平性。常结合全局、租户、用户和接口维度,注意槽位与原子性需求。

使用应用时间有哪些风险?#

多实例时钟偏差会影响窗口与补充计算,时间回退也需要处理。可选统一时间来源并校验时间差,同时把毫秒/秒单位定义清楚。

Redis 如何实现限流?固定窗口和滑动窗口怎么选?
https://blog.xqcherry.top/posts/interview/redis/redis-rate-limiting/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0