Redis缓存需防范穿透、雪崩、击穿三类问题:穿透用空值占位+布隆过滤;雪崩靠过期时间随机化+永不过期主动更新;击穿借分布式锁+提前刷新+本地缓存兜底。

Redis 作为高性能缓存中间件,光会 set/get 远远不够。真正影响系统稳定性和数据一致性的,是缓存策略的设计与过期机制的合理运用。
缓存穿透:空值也要“记下来”
当大量请求查询根本不存在的 key(比如无效 ID、恶意刷量),每次都会击穿缓存直查数据库,造成压力陡增。单纯依赖 Redis 的过期机制无法解决——因为压根没存。
- 对查询结果为 null 的情况,也写入一个特殊占位值(如 "null" 或空对象),并设置较短过期时间(如 2~5 分钟)
- 在业务逻辑中统一判断返回值是否为占位符,避免误用
- 配合布隆过滤器(Bloom Filter)前置拦截,进一步降低无效查询率(Python 可用 pybloom-live 库)
缓存雪崩:别让过期时间“扎堆”
大量 key 在同一时刻集中过期,导致请求瞬间涌向数据库,引发连锁反应。常见于批量写入时未打散 TTL。
- 设置过期时间时加入随机偏移量:ex=random.randint(3600, 7200)(1~2 小时内浮动)
- 对核心数据启用永不过期 + 主动更新机制(如后台定时任务刷新缓存)
- 使用 Redis 的 EXPIRE 命令单独控制关键 key 的生命周期,而非依赖写入时固定 TTL
缓存击穿:热点 key 要“加把锁”
某个极热 key(如首页 banner、秒杀商品)过期瞬间,多个并发请求同时发现缓存失效,全部回源查库,造成瞬时 DB 压力峰值。
立即学习“Python免费学习笔记(深入)”;
- 用 Redis 实现分布式锁(SET key value EX seconds NX),只允许一个请求加载数据,其余等待后读缓存
- 提前主动刷新:在 key 过期前 1~2 分钟,由后台线程异步重建缓存(即“永不过期 + 延迟双删”变体)
- 本地缓存兜底:对超高频只读数据,可在应用层加一层短时效(如 10 秒)的内存缓存(functools.lru_cache 或 cacheout)
过期策略不是“设了就完事”
Redis 默认采用惰性删除 + 定期抽样清理,不保证 key 到点立刻消失。实际过期行为受配置和负载影响。
- 通过 CONFIG GET hz 查看 serverCron 执行频率(默认 10,即每 100ms 检查一次),高频场景可调高(但增加 CPU 开销)
- 避免依赖精确过期时间做业务逻辑(如“过期即作废”的权限校验),应结合业务时间戳二次判断
- 用 TTL key 和 PTTL key 动态观察剩余寿命,调试时比盲目设值更可靠
缓存不是银弹,而是权衡的艺术。策略选对了,Redis 才从“加速器”变成“稳定器”。










