Redis 缓存穿透 / 击穿 / 雪崩的防御组合拳

郑

郑后端

· 阅读 472

分享

缓存用不好,高并发下数据库会被瞬间打垮。三类经典问题各有成因和对策,要组合使用。

围绕「Redis 缓存穿透 / 击穿 / 雪崩的防御组合拳」,很多讨论集中在技巧层面,但Redis 缓存与内存治理的核心其实是工程纪律:备份是否可恢复、变更是否可回滚、容量是否可预估。把这三件事做扎实,绝大多数故障都可以避免或快速收敛。

Redis 缓存穿透 / 击穿 / 雪崩的防御组合拳

缓存穿透(查根本不存在的数据)

对空结果也做短 TTL 缓存;用布隆过滤器提前拦截非法 key;在接口层做参数校验与限流,挡住恶意刷不存在的 id。

缓存击穿(热点 key 过期瞬间)

热点 key 用逻辑过期 + 异步重建;用互斥锁或单飞(singleflight)保证同一时刻只有一个请求回源重建,其余等待复用结果。

缓存雪崩(大量 key 同时过期或实例宕机)

过期时间加随机抖动,避免集中失效;用多级缓存;Redis 做高可用(主从 + 哨兵 / 集群);服务侧预置降级与限流兜底。

缓存一致性

更新采用"先写数据库、再删缓存"(Cache-Aside),必要时用延迟双删;对一致性要求不高的场景接受短暂不一致。

小结:缓存策略要始终围绕"保护数据库"来设计,并提前预置降级方案,别等被击穿才临时抱佛脚。

Redis 缓存穿透 / 击穿 / 雪崩的防御组合拳 Redis 缓存穿透 / 击穿 / 雪崩的防御组合拳

大 key、热 key 与淘汰策略同样要提前设计

穿透、击穿、雪崩是并发场景下的三类经典故障,但很多线上问题其实出在更朴素的地方:单个 key 过大、某个 key 被过度集中访问、内存写满后的淘汰行为与业务预期不符。这些问题在流量上来之前几乎没有症状。

  • 大 key:把大集合、大字符串拆分成多个小 key 或改用分片结构,避免单次读写长时间阻塞实例;定期扫描 key 大小分布,对异常增长的对象做拆分或外置到对象存储。
  • 热 key:对访问高度集中的 key 做本地缓存或多副本打散,防止单个分片被打满而其余分片空闲,集群模式下尤其要注意 key 的散列是否均匀。
  • 过期抖动:批量写入时给 TTL 加随机偏移,避免同一时刻集中失效;对必须常驻的基础数据不要设置过期时间。
  • 淘汰策略:先明确实例是当缓存用还是当存储用。当缓存用时允许淘汰并预置回源逻辑,当存储用时必须保证内存余量、开启持久化并配置水位告警。

监控上重点盯住命中率、内存使用率、慢查询与连接数这几条曲线:命中率骤降往往意味着缓存策略或数据分布发生了变化,它通常比数据库告警更早出现,是最有价值的前置信号。把这些指标接进日常巡检,缓存才不会变成只在出事时才被想起的黑盒。

Redis 缓存与内存治理的三个基本盘

其一是可恢复性:备份的价值不在于「做了」,而在于「能恢复」,定期演练恢复流程比增加备份份数更重要。其二是可回滚性:任何结构或参数变更都应有回退路径,避免把生产当试验场。其三是可预估性:容量与增长趋势要有数据支撑,而不是等到告警才响应。

这三个基本盘稳固之后,再去做性能调优和架构升级,风险会小很多。

从排查到预防:把经验沉淀为机制

  • 慢的问题先定位再动手:用执行计划与监控数据说话,避免凭感觉改索引、改参数。
  • 变更留痕:每一次调整记录原因与预期,便于复盘与回退。
  • 容量预警前置:为存储、连接数、内存等关键水位设置提前量告警。
  • 演练常态化:把恢复演练、切换演练纳入日常,而不是出事才第一次做。

机制化的沉淀,能让Redis 缓存与内存治理从「个人经验」变成「团队能力」。

#Redis#缓存#高并发