主题切换
缓存雪崩
一、定义
大批量缓存Key在同一时间段集体过期,或是Redis整个实例宕机,导致所有请求无法命中缓存,全部直接访问数据库,瞬间压垮数据库。 缓存击穿是单个热点Key过期,缓存雪崩是海量Key集体失效,二者影响量级差异极大。
二、两种触发原因
- 批量key同时过期:大量数据设置完全相同的过期时间,在同一时刻集体失效。
- Redis宕机故障:Redis集群断电、服务异常不可用,所有请求失去缓存支撑,全部查询数据库。
三、四大解决方案详解
① TTL添加随机偏移(事前预防,解决批量过期问题)
- 原理:在统一的基准过期时长基础上,追加30~900ms随机时间,错开每条key的过期节点。
- 举例:基准过期时间7200秒,不同key分别设置为 7200+56秒、7200+321秒,避免同一时间批量失效。
- 作用:从根源打散过期时间,杜绝因大批量key同时过期引发的雪崩。
- 局限:仅能解决过期型雪崩,无法应对Redis宕机场景。
② Redis高可用架构(解决Redis宕机问题)
- 哨兵Sentinel架构 一主多从部署,哨兵进程实时监控节点状态。主节点宕机后,哨兵自动从从库中选举新主节点,实现故障自动切换,业务无需修改代码。
- Redis Cluster集群 数据分片存储在多台节点上,单个分片节点故障仅影响对应分片数据,不会造成全量缓存失效。 作用:实现Redis节点故障自动容灾,保障缓存整体可用性,应对服务宕机型雪崩。
③ 限流+降级(网关兜底,故障发生后保护数据库)
限流
限制单位时间内允许进入系统的请求总量,拦截超额流量,避免大量请求冲击数据库。
- 实现位置:Nginx、SpringCloud Gateway 等网关层
- 示例:接口每秒仅放行200个请求,超出部分直接拒绝,不再进入业务逻辑与数据库查询
- 常用算法:令牌桶、漏桶
降级
当缓存大面积失效、系统压力陡增时,暂时关停非核心业务,直接返回预设兜底数据,优先保障核心接口可用。
- 示例:商品详情页缓存失效后,不再查询数据库,返回静态默认数据;同时关闭商品推荐、浏览记录等非核心功能
- 目的:牺牲非核心业务,保护核心业务与数据库稳定
总结:限流拦截超额流量,降级舍弃非核心功能,二者配合是雪崩故障的最后一道防线。
④ 多级本地缓存(Redis宕机备用方案)
- 访问链路:网关 → 应用本地缓存(Caffeine/Guava) → Redis → MySQL,本地缓存数据存储在JVM内存中。
- 执行逻辑:优先读取本地缓存,未命中再查询Redis;若Redis整体宕机,直接使用本地缓存,不再访问数据库。
- 组件说明
- Caffeine:高性能本地缓存,高并发场景生产首选
- Guava:经典本地缓存,使用简单
- 缺点:本地缓存与Redis数据会出现短暂不一致,适用于可容忍短暂脏读的业务。
四、三大缓存问题汇总区分
- 缓存穿透:查询数据库不存在的数据,缓存、数据库均无有效数据,多由恶意请求、非法参数引发。
- 缓存击穿:单个热点key过期,海量并发访问同一条存在的数据。
- 缓存雪崩:大批量key集体过期 或 Redis整体宕机,全品类缓存失效,海量请求集中落库。
五、面试高频问题解析
问:什么是缓存雪崩,和缓存击穿有什么区别?
答: 缓存雪崩分为两种情况,一是大批量缓存key同时过期,二是Redis服务整体宕机,海量请求全部直达数据库。击穿只是单个热点key过期,二者失效范围、影响规模完全不同。
问:如何解决大批量key同时过期引发的雪崩?
答: 给过期时间增加随机偏移量,打散所有key的过期时间,避免集中失效,属于事前预防方案。
问:Redis宕机导致雪崩该如何应对?
答: 部署哨兵或集群架构实现高可用,完成故障自动转移;同时搭配Caffeine、Guava等本地缓存做二级兜底,Redis不可用时直接读取本地缓存。
问:限流和降级分别起到什么作用?
答: 限流控制请求流量大小,阻挡超额请求进入系统;降级关闭非核心功能、返回兜底数据。二者在缓存雪崩发生后,用来保护核心业务和数据库。
问:简述穿透、击穿、雪崩三者的核心区别?
答: 穿透是查询不存在的数据;击穿是单个热点key过期;雪崩是批量key过期或Redis宕机,三者成因、影响范围、解决方案均不相同。