什么是Redis缓存击穿、穿透、雪崩?

78 阅读2分钟

1、首先我们来看一下正常的数据访问

image.png

2、缓存穿透

  • 问题描述:若用户大量\color{#d21f1f}{大量}的去中查询\color{#d21f1f}{查询}数据库中不存在\color{#d21f1f}{不存在}的数据(数据库命中),就会给数据库带来大量的负载导致数据库挂掉。 image.png

  • 解决方案

    1. 缓存空的对象:发现在数据库中不存在Key值,针对Key值缓存一个空的对象到缓存中(key,null);当用户再次访问返回空,并且设置空结果的过期时间会很短,最长不超过五分钟。 缺点:会造成内存大量浪费;2,返回NULL,对用户不友好。
    2. 布隆过滤器: 就是一个很长的二进制数组,如果Key存在数据库就是1,否则就是0。哈希函数越多,误差率越小。消耗的内存、时间越多
      存值:一个字符串比如:Kevin,经过3个(也可能多个)不同的Hash算法,算出对应的下标,下标改为1。意味着不同的Key可能对应相同的下标,从而导致删除时将删除其他的Key的下标。
      检查:前端来了一个请求,由布隆过滤器判断,经过3个(也可能多个)不同的Hash算法得到索引取值,若值都为1,则可能存在,将请求打到缓存。若有一个为0,这返回空。

      优缺点!
      优点: 1,所占空间非常小,由一串二进制数组组成;2,插入与查询的速度非常快,因为是基于Hash算法,时间复杂度为O(K),K代表用了几个Hash算法;3,保密性好,因为存储二进制数据,不储存原始数据。

      缺点: 1,很难去做删除操作,因为不同的Key可能对应相同的下标,从而导致删除时将删除其他的Key的下标;2,存在一定概率的误判,不可避免的问题,这个很好理解。

image.png image.png

3,缓存击穿

  • 问题描述:某个热点Key\color{#d21f1f}{某个热点Key},在同一时刻失效,从而将大量的并发请求热点Key打到数据库中,从而导致数据库挂掉。

  • 解决方案:
    1,使用分布式锁,多个线程需要去抢占这把锁,只有一个线程能抢到,从而访问数据库,并且将数据存到Redis缓存中,其他线程Sleep几毫秒,在去缓存中取。

4、缓存雪崩

  • 问题描述:大量的Key\color{#d21f1f}{大量的Key},在同一时刻失效,从而将大量的并发请求打到数据库中,从而导致数据库挂掉。

image.png

  • 解决方案:
  1. 设置缓存的失效时间。让他不要在同一时间全部失效。随机初始化失效时间。
  2. 将热点key平均的分布在不同的集群节点上。
  3. 设置定时任务,不断的刷新缓存。