解决 Redis 热 Key 问题,核心思路是分散热 Key 的访问压力,避免单个 Redis 节点因高频请求过载,具体可通过以下方法实现:
1. 热 Key 前置缓存
-
将热 Key 缓存到更靠近用户的位置,减少对 Redis 的直接请求:在应用服务器本地缓存(如 Guava Cache、Caffeine)中存储热 Key 数据,优先从本地读取,失效后再回源 Redis 更新。
-
利用 CDN 缓存静态类热数据(如商品详情页、活动配置),直接通过 CDN 响应用户请求,绕开 Redis。
2. 热 Key 拆分(最常用方案)
将单个热 Key 拆分为多个子 Key,分散到不同 Redis 节点:
- 原理:比如热 Key 为 user:10086,可按规则拆分为 user:10086:0、user:10086:1…user:10086:9(拆分数量根据压力调整),存储相同数据。
- 访问时:客户端通过哈希或随机算法选择其中一个子 Key 读取,使原本集中在一个 Key 的请求,分散到 10 个 Key 及对应 Redis 节点,压力降低 90%。
3. 主从/哨兵/集群架构扩容
通过 Redis 集群部署,分散单个节点的压力:
- 主从复制:主节点写入,从节点分担读请求(热 Key 多为读请求),通过读写分离将读压力分散到多个从节点。
- Redis Cluster 集群:将热 Key 及其拆分后的子 Key,通过哈希槽分配到不同集群节点,避免单个节点承载所有热 Key 请求。
4. 调整 Key 过期策略
-
避免热 Key 集中过期引发的“缓存雪崩”,间接缓解热 Key 压力:给热 Key 设置随机过期时间(如基础过期时间 + 5~10 分钟随机值),避免大量热 Key 同时失效,导致请求瞬间涌入数据库。
-
对核心热 Key(如活动配置)设置永不过期,通过后台线程定时更新数据,确保缓存始终有效。
5. 业务层优化
从源头减少热 Key 的请求频率:
- 合并高频请求:比如用户频繁查询“商品库存”,可将多次单个查询合并为批量查询,减少请求次数。
- 限流降级:对热 Key 接口设置限流(如用 Redis + Lua 实现令牌桶),超出阈值时返回默认值或降级页面,保护 Redis 节点不被压垮。
6. 监控和报警
- 通过对数据访问的监控,对于不可预知的热点key,我们一般可以接入热点探测系统,定期上报我们对应的key的调用次数,后面通过sdk通知各个节点进行数据的缓存,来应对这些热点key的访问。