Redis缓存穿透、缓存击穿、缓存雪崩的介绍及其解决方案

2021/10/12 2:14:11

本文主要是介绍Redis缓存穿透、缓存击穿、缓存雪崩的介绍及其解决方案,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

首先,来画一张图了解下缓存处理的流程

 

 

 

 

 

 

 

 

 

 

 

 

 

一、缓存穿透

  描述:

  缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求查询该数据,导致数据库压力过大。

  解决方案:

  1、接口校验

  如鉴权校验、数据合法性校验

  2、布隆过滤器

  将数据库中所有的查询条件,放入布隆过滤器中,当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃。

  3、缓存空结果

  当没有命中缓存时,也没有从数据库取到数据时,我们给它缓存一个空结果,并且设置一个较短的过期时间(例如30s),之后当有请求访问时,可以直接从缓存中获取,保护后端数据源。   

  这个解决方案会存在两个问题:

  1.会需要更多的空间来存储更多的键,因为这当中可能会产生很多的空值键;

  2.数据一致性的问题,即时给空值设定了过期时间,缓存层和存储层还有会有一定时间的不一致,这对需要保持数据一致性的业务会有影响。

   

二、缓存击穿

  描述:

   缓存击穿是缓存中没有但数据库有的数据(一般是“热点数据”缓存时间到期了),这个时候由于并发量特别大,读缓存的时候读取不到数据,都同时去数据库读取数据了,导致数据库的压力瞬间增大,

  解决方案:

   1、设置热点数据永不过期

   2、加互斥锁 

  当多个线程同时去数据库查询这一条数据时,我们可以在第一个查询时使用互斥锁来锁住它,其他的线程走到这一步拿不到锁就进入等待的状态,等第一个线程查完数据,写入缓存后。后面的线程进来就可以直接走缓存了。

  贴代码,仅供参考:

 1 static Lock reenLock = new ReentrantLock();
 2     public Object getData() throws InterruptedException{
 3         //从缓存中获取数据
 4         Object object = getDataFromRedis();
 5         if(object == null){
 6             if(reenLock.tryLock()){
 7                 try {
 8                     System.out.println("拿到锁,从数据库中获取数据并写入缓存中");
 9                     //从数据库中查询数据
10                     object = getDataFromDB();
11                     //写入缓存
12                     setDataToRedis(object);
13                 } finally {
14                     reenLock.unlock();// 释放锁
15                 }
16             }else{
17                 object = getDataFromRedis();// 先查一下缓存
18                 if (object == null) {
19                     System.out.println("我没拿到锁,缓存也没数据,先等待一下");
20                     Thread.sleep(100);
21                     return getData();// 重试
22                 }
23             }
24         }
25         return object;
26     } 

 

三、缓存雪崩

  描述:

  缓存雪崩与缓存击穿不同的一点是,缓存雪崩是指大量的热点Key设置了相同的过期时间,导致缓存在同一时刻大量失效,这时由于并发量过大,会导致所有的请求都需要到数据库去读取数据,数据库压力骤增,引起雪崩。

  解决方案:

  1、过期时间打散

  既然是因为大量缓存集中失效导致的,那第一想到的应该是让它们不要集中失效就好了。可以给缓存的过期时间加一个随机值时间,使得每一个Key的过期时间都错开来,不会在同一时刻失效。

  2、热点数据永不过期

  3、加互斥锁

  该方式和缓存击穿一样,按Key维度去加锁,同一个Key,指允许一个线程去请求数据库,后续的都从缓存中读取。

最后

欢迎补充,点个推荐鼓励一下吧!



这篇关于Redis缓存穿透、缓存击穿、缓存雪崩的介绍及其解决方案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程