Redis缓存穿透、击穿、雪崩
AI生成声明: 本文档由AI辅助生成,旨在提供Redis缓存穿透、击穿、雪崩问题的完整解决方案。
缓存穿透、击穿、雪崩是Redis使用中的三大经典问题,理解并解决这些问题对于保证系统稳定性至关重要。
核心问题
缓存穿透(Cache Penetration)
定义:
- 查询不存在的数据
- 缓存和数据库都没有
- 大量请求直接打到数据库
原因:
- 恶意攻击
- 业务逻辑缺陷
- 数据确实不存在
解决方案:
布隆过滤器
java// 查询前先检查布隆过滤器 if (!bloomFilter.mightContain(key)) { return null; }缓存空值
java// 即使数据不存在也缓存 if (data == null) { redis.set(key, "", 60); // 设置短过期时间 }参数校验
- 对请求参数进行校验
- 过滤非法请求
缓存击穿(Cache Breakdown)
定义:
- 热点数据过期
- 大量请求同时访问数据库
- 数据库压力骤增
原因:
- 热点数据过期
- 并发访问量大
解决方案:
互斥锁
java// 使用分布式锁 String lockKey = "lock:" + key; if (redis.setNx(lockKey, "1", 10)) { try { data = loadFromDB(); redis.set(key, data); } finally { redis.del(lockKey); } } else { // 等待其他线程加载 Thread.sleep(100); return getFromCache(key); }永不过期
- 热点数据设置永不过期
- 异步更新缓存
提前续期
- 在过期前异步刷新
- 保证数据始终可用
缓存雪崩(Cache Avalanche)
定义:
- 大量缓存同时过期
- 大量请求打到数据库
- 数据库压力过大
原因:
- 缓存过期时间设置相同
- Redis服务宕机
- 大量数据同时失效
解决方案:
过期时间随机化
java// 在基础时间上增加随机值 int expireTime = 3600 + random.nextInt(600); redis.set(key, value, expireTime);多级缓存
- 本地缓存 + Redis
- 降低Redis压力
熔断降级
- 检测到异常时熔断
- 返回默认值或错误提示
高可用架构
- Redis主从 + 哨兵
- Redis Cluster集群
预防措施
监控告警
- 监控缓存命中率
- 监控数据库QPS
- 设置告警阈值
限流
- 对数据库访问限流
- 保护数据库
降级策略
- 缓存不可用时降级
- 返回默认数据
常见面试题
三种问题的区别?
- 穿透:数据不存在
- 击穿:热点数据过期
- 雪崩:大量数据同时过期
如何预防缓存雪崩?
- 过期时间随机化
- 多级缓存
- 高可用架构
布隆过滤器的原理?
- 位数组 + 多个哈希函数
- 可能存在误判
- 不存在一定不存在