2023-03-26

Redis缓存穿透和雪崩

缓存穿透

缓存穿透的概念:用户想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透

解决方案

  • 布隆过滤器

布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力

jiclc.png

  • 缓存空对象

当存储层不命中后,即使返回空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源

jisTr.png

存在的问题

1.需要更多空间存储空键

2.即使设置了过期时间,但是和存储层的时间窗口不一致,不能保持一致性


缓存击穿

这里需要注意和缓存击穿的区别,缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

当某个key在过期的瞬间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访 问数据库来查询最新数据,并且回写缓存,会导使数据库瞬间压力过大。

解决方法

  • 设置热点数据永不过期

  • 加互斥锁

分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。


缓存雪崩

缓存集中失效,redis宕机

jiYcG.png

解决方案

  • redis高可用

搭建集群,异地多活

  • 限流降级

缓存失效后,通过加锁或者队列来控制数据库写缓存的线程数量

  • 数据预热

正式部署前预先访问一遍可能的数据,尽可能手动触发加载缓存,设置不同的缓存时间,让缓存失效的时间点尽量均匀