Redis 缓存穿透、击穿、雪崩 的区别与解决方案
前言
Redis 是一个高性能的键值数据库,广泛应用于缓存、会话存储、实时数据分析等场景。然而,在高并发的环境下,Redis 缓存可能会遇到 缓存击穿、缓存穿透 和 缓存雪崩 这三大问题。这些问题不仅影响系统的稳定性和性能,还经常出现在面试题中,值得我们深入了解🤏。
1. 缓存穿透
定义
缓存穿透指的是查询一个不存在的数据时,缓存层和数据库层都会返回空结果,导致每次请求都直接访问数据库,从而失去缓存的加速作用,增加数据库的负担。
“穿透”可以简单的理解为:缓存和数据库都不存在要查询的数据,请求直接“穿透”了缓存。
场景
例如:用户请求一个不存在的商品ID,由于缓存和数据库中都没有该商品的信息,请求直接穿透到数据库,增加数据库的压力。
解决方案
-
布隆过滤器
使用布隆过滤器缓存不存在的请求,避免每次都查询数据库。布隆过滤器可以高效判断某个元素是否在集合中,减少不必要的数据库查询。 -
缓存空值
当查询结果为空时,可以将空值缓存一段时间(如 1-5 分钟),避免频繁穿透。这样即使请求再次到来,也能从缓存中返回空值,减少数据库查询。
流程图
2. 缓存击穿
定义
缓存击穿是指缓存中的某些数据在失效后,大量请求同时访问该数据,导致所有请求直接穿透到数据库,增加数据库压力,甚至可能导致数据库崩溃。
“击穿”可以简单的理解为:缓存不存在,但是数据库存在要查询的数据,请求直接“击穿”了缓存。
场景
例如:某个商品详情数据在缓存中过期,多个用户同时请求该商品数据,由于缓存失效,这些请求直接访问数据库,造成数据库负载骤增。
解决方案
-
互斥锁
在缓存失效时,使用分布式锁确保只有一个请求访问数据库并更新缓存,其余请求等待缓存更新完毕后再从缓存中获取数据,避免同时访问数据库。 -
缓存预热
在系统启动时,提前将常用数据加载到缓存中,减少缓存失效的概率,确保热点数据一直在缓存中。 -
合理的缓存失效时间
根据数据访问频率和业务需求合理设定缓存过期时间,避免过短的失效时间引起频繁的缓存更新和数据库访问。
流程图
3. 缓存雪崩
定义
缓存雪崩是指大量缓存数据在同一时间失效,导致大量请求同时访问数据库,给数据库带来巨大压力,甚至可能导致数据库崩溃。
“雪崩”可以简单的理解为:大量缓存同一时间失效,缓存“雪崩”了。
场景
例如:大量缓存数据设置了相同的过期时间,所有缓存数据在某一时刻失效,导致大量请求同时访问数据库,可能引发雪崩效应。
解决方案
-
错开缓存过期时间
在缓存过期时间上增加随机偏移量,错开过期时间,减少缓存同时过期的情况。 -
使用永久缓存
对于不经常变化的数据,可以使用永久缓存,避免频繁失效,减少数据库访问。 -
降级处理
当缓存系统发生故障时,启用降级机制,将部分请求转发至备用缓存或返回默认值,减轻数据库压力。
流程图
总结
- 缓存穿透:查询数据时 缓存和数据库都不存,使用 布隆过滤器 和 缓存空值 避免每次都访问数据库。
- 缓存击穿:查询数据时 缓存不存在,数据库存在,使用 互斥锁、缓存预热 和 合理的过期时间 解决。
- 缓存雪崩:查询数据时 大量缓存同一时间失效,通过 错开缓存过期时间、使用永久缓存 和 降级处理 应对。