在使用 Redis 做缓存时,缓存穿透、缓存击穿、缓存雪崩是后端开发高频遇到的三大问题,很多人容易混淆这三者概念,本文结合场景简单梳理。
缓存穿透:查询一个根本不存在的数据,缓存和数据库都查不到。请求直接穿透缓存,打到数据库。 比如用户查询 id=-1 的商品,Redis 没有这个 key,接着去查 MySQL,大量这类请求会压垮数据库。
解决方案:
- 缓存空值,将查询结果为空的数据存入 Redis,设置较短过期时间;
- 使用布隆过滤器,提前拦截不存在的 key,在请求进入缓存前过滤无效查询。
缓存击穿:某个热点 key 过期的瞬间,大量并发请求同时过来,全部打到数据库。 比如秒杀爆款商品,key 刚好过期,成千上万请求绕过 Redis 直连数据库。
方案:互斥锁(分布式锁),同一时间只放行一个请求去更新缓存;或者热点 key永不过期,在后台异步主动更新缓存,避免过期瞬间的并发冲击。
缓存雪崩:大量缓存 key 在同一时刻集体过期,大量请求全部落到数据库,数据库压力瞬间飙升,甚至宕机。
和击穿区别:击穿是单个热点 key,雪崩是大批量 key 同时失效。
解决思路:
- 给 key 的过期时间增加随机偏移量,错开过期时间;
- 搭建 Redis 集群实现高可用,防止单点故障;降级熔断,数据库压力过大时直接返回兜底数据,拒绝部分请求。
总结
- 穿透:查不存在的数据,一直打 DB
- 击穿:单个热点 key 过期,并发打 DB
- 雪崩:大量 key 同时过期,集体打 DB
在实际项目中,优先通过设置过期时间随机值预防雪崩;热点业务使用分布式锁或永久缓存防止击穿;布隆过滤器 + 缓存空值解决穿透。合理组合方案,才能保障缓存架构稳定。