Redis 缓存穿透击穿雪崩的区分与对策
该文章由AI生成,仅为SEO优化测试,相关内容不保证准确!!!
引言
用了 Redis 缓存,数据库还是被打挂?穿透、击穿、雪崩三种场景都会导致“缓存没挡住流量”,但成因与对策完全不同。区分清楚,才能对症下药。
一、缓存穿透:查不存在的数据
场景:请求的数据在缓存和数据库中都不存在(如恶意传入 id=-9999)。每次请求都穿透缓存直击数据库,攻击者可以用随机 ID 打穿你的库。
对策:① 缓存空值:数据库查不到也写入一个短 TTL 的空标记(如 60 秒),下次请求直接返回;② 布隆过滤器:启动时把所有合法 id 放入布隆过滤器,请求先过滤,不存在的直接拒绝,内存占用小;③ 参数校验:id 必须为正整数、格式校验,在入口就拦掉明显非法的请求。穿透多与攻击相关,配合 WAF/频控识别高频异常请求。
二、缓存击穿:热点 key 过期瞬间
场景:某个热点 key(如秒杀商品详情)在过期的一瞬间,大量并发同时请求,都未命中缓存,同时打到数据库——瞬间把库压垮。
对策:① 互斥锁:缓存未命中时,只允许一个请求去数据库加载(用 SETNX 加锁),其他请求短暂等待后读新缓存;② 热点 key 永不过期:不设 TTL,由后台线程定时主动更新,配合版本号避免脏读;③ 逻辑过期:值里存过期时间,发现逻辑过期后异步更新,期间返回旧数据,避免阻塞。核心思想:把“并发打库”变成“单次打库”。
三、缓存雪崩:大量 key 同时失效
场景:大批 key 在同一时间集中过期(如用统一 TTL 批量写入),或 Redis 实例宕机,缓存整体失效,数据库瞬间承受全量请求。
对策:① 过期时间打散:基础 TTL + 随机偏移(如 3600+random(600) 秒),避免集中失效;② 多级缓存:本地缓存(进程内)+ Redis 两级,Redis 抖动时本地兜底;③ 高可用:Redis 主从+哨兵或集群,避免单点宕机导致全量失效;④ 限流降级:缓存失效的极端情况下,对数据库访问限流保核心,非核心功能降级返回默认值。
四、快速区分与排查
排查口诀:看请求的数据存在与否——不存在是穿透(恶意或参数错误);存在且是单 key 失效是击穿(热点过期);大面积同时失效是雪崩(集中过期或宕机)。监控上重点看缓存命中率:命中率骤降是三类问题的共同信号,再按上述特征定位具体类型。
总结
穿透查“不存在的数据”(空值缓存+布隆过滤器),击穿防“热点过期瞬间”(互斥锁/逻辑过期),雪崩防“集体失效”(TTL 打散+高可用)。三者共同的前提是缓存命中率的持续监控——命中率下降就是预警信号。