缓存雪崩
更新: 2025/12/6 字数: 0 字 时长: 0 分钟
在某一时刻大量缓存数据同时过期或者缓存系统突然不可用,导致大量请求直接涌入后端数据库,造成数据库负载过高甚至崩溃的现象
核心问题
高并发场景下缓存层无法承担流量压力,从而将全部压力传导至数据库
两种触发情况,第一种是大多数key都设置了相同的过期时间,且都在整点统一加载,集中失效;第二种是缓存服务出现故障,所有缓存无法访问
解决方法
解决集体失效问题:
- 在固定的过期时间基础上增加一个随机值,避免集体失效,例如原本300秒过期,现在改为30分钟+(0~300秒),分散失效时间
- 使用逻辑过期代替物理过期,将过期时间作为数据存储在缓存中,应用层读取时判断是否逻辑过期,若过期则异步更新缓存,而不是真正删除,这样即时大量数据(看起来过期),也不会同时击穿,而是后台线程逐步重建 【从Redis获取数据,若存在但已逻辑过期,启动异步线程更新缓存,当前请求依旧返回旧值,若不存在,则同步加载】
解决缓存服务问题:
- 使用多级缓存架构,使用本地缓存作为第一层,Redis作为第二层,即使Redis短暂不可用或者过期,本地缓存依旧能缓冲部分请求
- 限流或者降级,限制请求速率,超出阈值的请求直接返回默认值或错误提示。 同时开启服务降级,在缓存和数据库都不可用时返回兜底数据(如静态页面、缓存快照)
- 缓存高可用部署,使用使用Redis主从+哨兵(Sentinel)避免单点故障。 数据分片存储,一台宕机不影响整体服务
缓存击穿
更新: 2025/12/6 字数: 0 字 时长: 0 分钟
针对单个热点key过期,被大量并发访问导致数据库压力剧增。解决方案是加互斥锁(如Redis分布式锁)控制只有一个线程去加载数据库。
缓存穿透
更新: 2025/12/6 字数: 0 字 时长: 0 分钟
查询一个不存在的数据,每次都会打到数据库。解决方案是布隆过滤器(Bloom Filter)拦截非法key,或对空结果也做缓存(空对象+短过期时间)。