Redis缓存穿透、缓存击穿、缓存雪崩
Redis缓存穿透、缓存击穿、缓存雪崩
缓存穿透
- DB中实际不存在该数据,缓存未命中,查询穿透至DB中
解决方式
- 查询时,对于不存在的数据,缓存中缓存默认值(可为null或其他值),该方式随着查询的缓存key增长或恶意攻击等方式,将造成缓存Key过多的问题
- 对于上述解决方案的负面影响,可维护一个不存在的查询Key(invalid)列表,其缓存数据增长量可在一定程度上缓解
- 使用布隆过滤器进行前缀过滤,确定不存在的Key,直接返回,可能存在的Key再经过缓存查询, DB查询的步骤,该方式可解决空间增长的问题,需要解决大数据量缓存预热的问题,且对于频繁删除的数据类型不适用
缓存击穿
- 对于同一缓存Key,在缓存过期或缓存不存在时,大并发量同时请求该数据,导致大并发量请求需同时访问DB
- 缓存服务不可用
解决方式
- 核心思想,缓存不过期或缓存失效时不要直接驱逐出缓存组件中,使用缓存预热、查询时异步线程更新、写入时更新、定时更新等方式,保证数据缓存组件内存在,该方案可能导致短暂的数据一致性问题,业务上注意斟酌
- 请求限流或服务降级,保证并发不超出DB承载的上限
- 互斥锁,对于并发请求,仅允许一个请求访问到DB,获取数据后存入缓存中,该方式会导致吞吐量下降
- 布隆过滤器同样可作为前置过滤,但对于存在的数据,仍然需要其他手段进行流量控制
- 缓存服务使用主从、哨兵、集群等部署模式,提升缓存服务的可用性
缓存雪崩
- 同一时间多个Key缓存失效或不存在,导致大量请求同时访问DB
- 缓存服务不可用
解决方式
- 不同Key,在基础缓存时间上,添加一定量的随机缓存时间,使Key不要再同一时间大批量失效,将可能得DB流量分散开来
- 请求限流或服务降级,保证并发不超出DB承载的上限
- 布隆过滤器同样可作为前置过滤,但对于存在的数据,仍然需要其他手段进行流量控制
- 缓存服务使用主从、哨兵、集群等部署模式,提升缓存服务的可用性