Redis限流算法实战
Redis 的五种数据结构各有特色,用对了才能发挥它的优势。很多人只用到了 String 和 Hash,却不知道 List、Set、ZSet 在特定场景下更合适。本文从应用场景出发,讲什么时候用什么类型。
一、计数器算法(固定窗口)
#
1.1 原理
将时间划分为固定窗口(如1分钟),每个窗口内允许N个请求 |
#
1.2 Redis实现
|
#
1.3 Lua原子实现
-- 计数器限流(原子操作) |
|
#
1.4 缺点
临界问题: |
二、滑动窗口算法
#
2.1 原理
记录每个请求的时间戳,滑动统计窗口内的请求数 |
#
2.2 ZSet实现
|
#
2.3 Lua原子实现
-- 滑动窗口限流 |
三、漏桶算法
#
3.1 原理
请求先进入漏桶(队列),以固定速率流出处理 |
#
3.2 Redis实现
|
四、令牌桶算法
#
4.1 原理
以固定速率往桶里放令牌,请求需要获取令牌才能执行 |
#
4.2 Redis实现
|
五、算法对比
| 算法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 计数器 | 简单,内存小 | 临界问题 | 简单限流 |
| 滑动窗口 | 精确,无临界问题 | 内存占用大 | 精确限流 |
| 漏桶 | 平滑流量 | 无法应对突发 | 流量整形 |
| 令牌桶 | 允许突发,灵活 | 实现复杂 | 通用限流 |
六、Spring Boot整合
#
6.1 AOP限流
|
#
6.2 使用注解
|
#
6.3 全局异常处理
|
七、多级限流
#
7.1 分层限流
|
八、总结
| 实现方式 | 复杂度 | 精度 | 推荐场景 |
|---|---|---|---|
| 计数器 | 低 | 低 | 简单接口保护 |
| 滑动窗口 | 中 | 高 | 精确限流 |
| 漏桶 | 中 | 中 | 流量整形 |
| 令牌桶 | 中 | 高 | 通用限流(推荐) |
限流设计的核心原则:
- 多层防护:网关层、应用层、接口层逐级限流
- 粒度合理:按用户、IP、接口多维度限流
- 降级友好:限流时返回友好提示
- 监控告警:及时发现异常流量
- 动态调整:支持动态修改限流阈值
核心要点
String:简单的键值对,适合缓存、计数器
Hash:存储对象属性,适合用户信息、配置
List:有序列表,适合消息队列、最新列表
Set:无序去重,适合共同好友、抽奖
ZSet:有序集合,适合排行榜、积分系统
总结
选择合适的数据结构是使用 Redis 的关键。在实际项目中,根据业务需求选择合适的类型,可以提升性能和开发效率。