重修Redis之三:到底什么是缓存穿透,击穿,雪崩?(有图有文字)

在面试Redsi过成中,经常会谈及缓存穿透、缓存击穿、缓存雪崩这三种使用缓存遇到的问题。而这三种现象的本质都是服务跳过缓存直接访问db,对db造成一定的冲击,严重会直接崩掉。究竟该如何形象的描述出这三个问题以及预防发生呢?带着疑问开始思考。

一、什么是缓存穿透?

缓存穿透:Redis作为缓存服务器主要是用来缓存数据库中查询频率高但是修改频率低的数据。数据库中不存在的数据,缓存中自然也没有。用户每次发起请求,先查询缓存,缓存没有直接查询数据库,数据中也不存在也不会更新缓存。这样一来就相当于经过了两次次请求缓存时无效的,也可以理解为让过了缓存直接查询数据库。而这一情况如果被非发请求不停攻击,请求都打到数据库上,会对数据库造成压力,甚至会打崩数据库。

解决方案:

 (1)增加参数校验,不合法的数据直接return;

 (2)缓存空值,如果数据库中不存在时返回一个默认值更新到缓存,设置较短的失效时间,比如5分钟;

 (3)布隆过滤器BloomFilter:

           布隆过滤器的优点:占用内存空间很小,位存储;性能特别高。

           使用key的hash判断key存不存在将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。在缓存之前在加一层BloomFilter,在查询的时候先去BloomFilter去查询key是否存在,如果不存在就直接返回,存在再去查询缓存,缓存中没有再去查询数据库。

二、什么是缓存击穿?

缓存击穿:缓存击穿是指一个key非常热点,一个key扛住了大量请求,当这个key失效时,请求会击穿缓存打到DB上,造成某一时刻数据库压力增加。

解决方案:

(1)如果这个key是非常热点的数据,可以设置为用久有效,定时根据需求去更新缓存

(2)并发场景下,用户互斥锁来控制,当缓存失效时,查询数据库时更新缓存时加上锁。这样其他线程请求时,缓存已经更新。

三、什么是缓存雪崩?

缓存雪崩:可以说是缓存击穿的升级版本,缓存击穿是一个key失效,大量请求打到数据库,而缓存雪崩是在一个时间段内大量可key失效,也就是发生多个缓存击穿事件,这对于数据库来说是灾难级别的影响。

解决方案:

(1)最简单的做法:设置的不同的过期时间,让缓存失效的时间点均匀分布;

(2)加锁排队:mutex互斥锁解决,Redis的SETNX去set一个mutex key,当操作返回成功时,再进行加载数据库的操作并回设缓存,否则,就重试整个get缓存的方法;

(3)数据预热:缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存,用户直接查询事先被预热的缓存数据。可以通过缓存reload机制,预先去更新缓存,在即将发生大并发访问前手动触发加载缓存不同的key,类似mysql中innodb 的预热机制;

(4)多级缓存策略:C1为原始缓存,C2为拷贝缓存,C1失效时,可以访问C2,C1缓存失效时间设置为短期,C2设置为长期;

(5)定时更新缓存策略,实效性要求不高的缓存,容器启动初始化加载,采用定时任务更新或移除缓存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章