Redis缓存穿透/雪崩/击穿

目录

一 缓存穿透

1.什么是缓存穿透

2.解决方法

① 在请求api接口时对数据进行非法校验

② 在redis中对没有的数据作个标记

③ 布隆过滤器

二  缓存雪崩

1.什么是缓存雪崩

2.解决方法

三 缓存击穿

1.什么是缓存击穿

2.解决方法


一 缓存穿透

1.什么是缓存穿透

        我们使用redis请求数据的时候,正常流程是先去redis缓存中查找,如果查到了数据,那么就直接返回,不需要再去查数据库,如果没有查到,就需要去查询数据库。所以缓存穿透就是:我们大量的访问一个数据库中本身就不存在的数据,既然数据库中都不存再该数据,那么redis'缓存中肯定更加不可能有这个数据,所以每次请求都会访问数据库去查找,大量这样的请求就会导致数据库压力过大崩盘。

2.解决方法

        主要有三种解决方法:

① 在请求api接口时对数据进行非法校验

这个方法是最常规的方法,比如请求的id都是大于0的,那么我们就可以做出判断,如果请求参数id小于0,那么就直接不去访问数据库。但是这个方法只能判断非法的数据,如果数据不是非法的,但是数据库就是没有这个数据,那么这样还是没办法解决。

② 在redis中对没有的数据作个标记

如果访问一个数据库没有的数据,那么当我们去数据库中查找也是空的时候,我们可以在缓存到redis中的时候对这个数据做个标记,比如id为1的数据是空,那么我们就在redis存储1:null,这样下次我们继续查询id为1的数据发现redis中的到的数据是null,那么说明数据库中也没有这个数据,我们就不去数据库中再进行查询了。 

③ 布隆过滤器

就是当我们进行查询请求的时候,先使用布隆过滤器判断该数据是否不存在(注意:我这里说的是不存在,而不是存在,因为它只能判断出一定不存在的数据,后面会解释),如果数据不存在,那么就不需要再去访问数据库查找了。

什么是布隆过滤器?

我们在访问数据的时候,他会先把查找数据的key计算出一个哈希值,再把这个哈希值转换成一个字节数组去存储,然后如果数据库中有这个数据,它就会把对应字节数组中的值进行填充成1,这样说明这个key对应的值存在,然后我们查询的时候也是一样根据key的哈希值去字节数组中查找,如果查找这个key对应的字节数数组中的值是0,那么肯定说明这个key的数据不存在。

二  缓存雪崩

1.什么是缓存雪崩

        因为我们存储在redis中的数据一般都会设一个有效时间,因为这样也是为了解决空间,如果正常情况下,是不同时间段会有部分数据失效,这样再去查数据库,不会给数据库太多压力。但是如果某一个时刻大量数据同时失效了,那么这个时候就会有大量访问请求数据库,这样就会导致数据库压力过大,这就是缓存雪崩。

2.解决方法

既然知道了原因,那么解决方法也就是根据原因来。

1.我们可以把数据设置成永远不失效,但是这样显然也有弊端。

2.我们把数据设置不同的失效时间,这样就不会造成大量数据同一时间失效的情况。

3.我们可以设置第三方缓存,如spring自带的缓存。

三 缓存击穿

1.什么是缓存击穿

        它和缓存雪崩有点像,但是它是某一个热门数据失效,按道理来说一个数据失效关系不大,但是因为它是非常热门的数据,比如双十一购物信息数据啥的,这样就会导致,这个数据失效后,但是因为这个数据的访问量很大,从而在它失效的这一个时刻,仍然有大量请求去访问这个数据,从而全部都访问到数据库,造成数据库压力过大,这就是缓存击穿。

2.解决方法

主要提供两种方法:

1.那就是都能想到的,把这个数据有效时间设置为永久。

2.使用互斥锁方案:

   互斥锁和我们平时的锁是一样的,只是它锁的位置是访问数据库的过程,当有一个线程去访问数据库了,其他的线程还是去数据库访问这个数据,就会被锁住,不准它去访问数据库,然后让它不断循环查询redis,当第一个线程从数据库中得到数据同时存放到redis中,这样其他的线程就可以得到数据同时跳出循环,这样就避免了大量的请求都去访问数据库。

Redis缓存穿透/雪崩/击穿_第1张图片 

你可能感兴趣的:(缓存,redis,java)