Redis缓存问题的示例分析如下:
缓存穿透
当用户查询的数据在Redis和MySQL中均不存在时,恶意或高频请求会直接穿透缓存层,对MySQL造成冲击。例如,攻击者构造大量不存在的用户ID请求(如user_id=-1),若未加防护,MySQL需反复返回空结果,导致资源耗尽。解决方案包括:
- 缓存空对象:将MySQL返回的空结果缓存至Redis,并设置短过期时间(如5分钟)。此方法适用于空数据重复请求概率高的场景,但会占用缓存空间。
- 布隆过滤器:通过预加载可能存在的key到布隆过滤器中,拦截无效请求。例如,系统启动时将所有合法用户ID存入过滤器,后续请求先经过滤器判断,若key不存在则直接拒绝。此方法更高效,适用于空数据key分散且重复率低的场景。
缓存击穿
热点数据的key过期时,大量并发请求直接访问MySQL,导致瞬间压力激增。例如,某商品在促销期间被高频查询,若其缓存key在高峰期过期,可能引发数据库崩溃。解决方案包括:
- 热点数据永不过期:通过后台线程定期刷新缓存,避免key失效。此方法简单但需处理数据一致性问题,且代码复杂度较高。
- 分布式锁:请求先尝试获取锁,仅允许一个线程查询MySQL并更新缓存,其他线程等待。例如,使用Redisson实现分布式锁,确保同一时间只有一个请求访问数据库。此方法能显著降低数据库负载,但需防范死锁和线程阻塞风险。
缓存雪崩
大量缓存key同时过期,叠加高并发请求,导致MySQL压力骤增。例如,系统凌晨批量更新缓存时设置相同过期时间,次日高峰期所有key同时失效,引发雪崩。解决方案包括:
- 随机过期时间:为key设置不同过期时间(如基础时间+随机偏移),避免批量失效。例如,将原本统一的1小时过期改为50-70分钟随机值。
- 多级缓存与高可用:部署Redis集群,结合本地缓存(如Caffeine)构建多级缓存架构。即使部分Redis节点宕机,其他节点仍可提供服务,同时本地缓存可兜底部分请求。
总结:缓存穿透、击穿、雪崩的核心差异在于影响范围(单个key vs 批量key)和触发条件(数据不存在 vs key过期)。解决方案需结合业务场景选择,例如高频空查询用布隆过滤器,热点数据用分布式锁,批量过期用随机时间策略。