缓存穿透和雪崩

缓存穿透

默认情况下用户请求数据会从redis中查找如果没找到那么也就是缓存未命中,再在数据库中查找,可是一旦大量请求来的话,就会全部转移到数据库上,给数据库造成极大压力,导致数据库崩溃。

解决方法

  1. 布隆过滤器
    对所有可能查询用到的参数进行hash形式存储,以便快速确定是否有这个值在控制层进行拦截校验不通过直接打回,降低数据库压力
    在这里插入图片描述
    缓存空对象
    假如没有查询到一个参数,就在缓存中放一个空对象用于处理后序请求
    在这里插入图片描述
    这里有个问题是存放空对象也需要空间,且空对象存储效率不高,解决这个问题的缺陷就是设置较短过期时间。但是会影响数据的一致性
    即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。

缓存击穿

比如一个热点key过期,那么在这段时间请求数量倍增,同时对于某个key缓存不可用而导致击穿,但是其他的key依旧可以使用,造成db请求量大压力倍增比如热搜
解决办法
设置热点key永不过期,但是redis空间存满也会清除部分数据,这样做会占用空间一旦热点数据多了起来,占用很多空间。
加互斥锁
在反问key之前采用setnx来设置一个短期的key锁住当前的访问,访问结束再删除短期key,保证只有一个线程访问,这对于锁的要求很高

缓存雪崩

大量的key设置了相同过期时间导致很多缓存在同一时间失效,那么就会对db请求压力暴增导致redis宕机,使得所有数据需要从mysql中查询,导致波峰性的压力,导致存储层也会挂掉引发雪崩效应。
缓存批量过期不可怕,怕的是他宕机,导致mysql宕机引发雪崩效应,
解决方法

  1. redis高可用
    这个思想的含义是,既然redis有可能挂掉,那我多增设几台redis,这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群
  2. 限流降级
    这个解决方案的思想是,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
  3. 数据预热
    数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

猜你喜欢

转载自blog.csdn.net/weixin_43203363/article/details/114647933