redis缓存雪崩缓存击穿缓存穿透原因,解决方案?(代码片段)

紫薇哥哥 紫薇哥哥     2022-10-20     170

关键词:

缓存雪崩、缓存击穿、缓存穿透原因,解决方案?

缓存雪崩

由于设置缓存时,key都采用了相同expire,导致缓存在某刻同时失效,请求全部直到DB,DB瞬时负载过重而雪崩

解决方案

在原有失效时间基础上增加一个随机值,比如1~5分钟的随机,这样每个缓存的过期时间重复率就会降低,集体失效概率也会大大降低。

  • 首先环境保证redis高可用,主从+哨兵,redis cluster,避免全盘崩溃。
  • 接着用户并发请求后,服务会先通过hystrix限流&降级,再查本地Ehcache缓存,若没有再查redis,都没有,就查MySQL。
  • 最后,将MySQL中的结果写入ehcache和redis、即使 redis挂了,通过redis持久化,也能快速恢复缓存数据

缓存穿透

出现Redis中不存在的缓存数据。例如:访问id=-1的数据。可能出现绕过redis依然频繁访问数据库,称为缓存穿透,多出现在查询为null的情况不被缓存时

解决方案

最常见的布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

也有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

if(list==null)
// key value 有效时间 时间单位
redisTemplate.opsForValue().set(navKey,null,10, TimeUnit.MINUTES);
else
redisTemplate.opsForValue().set(navKey,result,7,TimeUnit.DAYS);

缓存击穿

缓存雪崩的区别在于这里针对某一key缓存,而前者是很多key。

通常使用缓存 + 过期时间的策略来帮助我们加速接口的访问速度,减少了后端负载,同时保证功能的更新,一般情况下这种模式已经基本满足要求了。

但如下两个问题如果同时出现,可能就会对系统造成致命的危害: 1. 这个key是一个热点key,访问量非常大 2. 缓存的构建是需要一定时间的。(可能是一个复杂计算,例如复杂的sql、多次IO、多个依赖(各种接口)等等)

于是就会出现一个致命问题:在缓存失效的瞬间,有大量线程来构建缓存(见下图),造成后端负载加大,甚至可能会让系统崩溃 。

解决方案

互斥锁

在缓存失效时(判断拿出来的值为空),不是立即去load db,而是 - 先使用缓存工具的某些带成功操作返回值的操作(Redis的SETNX)去set一个mutex key - 当操作返回成功时,再load db的操作并回设缓存;否则,就重试整个get缓存的方法。

public String get(key)
String value = redis.get(key);
if (value == null) // 缓存已过期
// 设置超时,防止del失败时,下次缓存过期一直不能load db
if (redis.setnx(key_mutex, 1, 3 * 60) == 1) // 设置成功
value = db.get(key);
redis.set(key, value, expire_secs);
redis.del(key_mutex);
else
// 其他线程已load db并回设缓存,重试获取缓存即可
sleep(50);
get(key); //重试

else // 缓存未过期
return value;

提前"使用互斥锁(mutex key):

在value内部设置1个超时值(timeout1), timeout1比实际的memcache timeout(timeout2)小。当从cache读取到timeout1发现它已经过期时候,马上延长timeout1并重新设置到cache。然后再从数据库加载数据并设置到cache中。伪代码如下:

v = memcache.get(key);
if (v == null)
if (memcache.add(key_mutex, 3 * 60 * 1000) == true)
value = db.get(key);
memcache.set(key, value);
memcache.delete(key_mutex);
else
sleep(50);
retry();

else
if (v.timeout <= now())
if (memcache.add(key_mutex, 3 * 60 * 1000) == true)
// extend the timeout for other threads
v.timeout += 3 * 60 * 1000;
memcache.set(key, v, KEY_TIMEOUT * 2);

        // load the latest value from db  
        v = db.get(key);  
        v.timeout = KEY_TIMEOUT;  
        memcache.set(key, value, KEY_TIMEOUT * 2);  
        memcache.delete(key_mutex);  
     else   
        sleep(50);  
        retry();  
      
  

限流

如使用 hystrix 或者 sentinel限流即可。现在该技术已较成熟,足够使用

redis系列缓存击穿穿透雪崩解决方案详解

文章目录前言一、击穿1.介绍2.产生原因3.解决方案二、穿透1.介绍2.产生原因3.解决方案三、雪崩1.介绍2.产生原因3.解决方案结尾前言众所周知,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生... 查看详情

redis系列缓存击穿穿透雪崩解决方案详解

文章目录前言一、击穿1.介绍2.产生原因3.解决方案二、穿透1.介绍2.产生原因3.解决方案三、雪崩1.介绍2.产生原因3.解决方案结尾前言众所周知,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生... 查看详情

redis的缓存穿透缓存雪崩缓存击穿问题的概念与解决办法(代码片段)

详细介绍了Redis的缓存穿透、缓存雪崩、缓存击穿等问题的概念与解决办法。文章目录1缓存穿透1.1什么是缓存穿透?1.2怎么解决1.3BloomFilter布隆过滤器1.3.1BloomFilter的原理1.3.2BloomFilter的优缺点1.3.3GuavaBloomFilter1.3.4RedisBloomFilter2... 查看详情

redis缓存穿透缓存击穿缓存雪崩的原理和解决办法(代码片段)

Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法1.前言2.缓存穿透的解决办法3.缓存击穿解决办法4.缓存雪崩的解决办法1.前言在大数据时代,由于网络请求的并发,导致的数据库I/O开销巨大,所以为了缓解数据库的压力,缓... 查看详情

redis缓存穿透缓存击穿缓存雪崩的原理和解决办法(代码片段)

Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法1.前言2.缓存穿透的解决办法3.缓存击穿解决办法4.缓存雪崩的解决办法1.前言在大数据时代,由于网络请求的并发,导致的数据库I/O开销巨大,所以为了缓解数据库的压力,缓... 查看详情

redis的缓存问题之缓存穿透缓存雪崩缓存击穿(代码片段)

目录一、什么是缓存穿透?二、常见的解决方案有两种:1、缓存空对象2、布隆过滤综上所述三、编码解决商品查询的缓存穿透问题四、缓存雪崩问题及解决思路1、什么是缓存雪崩?五、缓存击穿问题及解决思路 1、... 查看详情

redis——缓存穿透缓存击穿缓存雪崩分布式锁(代码片段)

...录:1.缓存穿透1.1什么是缓存穿透?1.2缓存穿透的解决方案2.缓存击穿2.1什么是缓存击穿?2.2缓存击穿的解决方啊3.缓存雪崩3.1什么是缓存雪崩?3.2缓存雪崩的解决方案4.分布式锁4.1使用setnx+del实现分布式锁的添... 查看详情

redis——缓存穿透缓存击穿缓存雪崩分布式锁(代码片段)

...录:1.缓存穿透1.1什么是缓存穿透?1.2缓存穿透的解决方案2.缓存击穿2.1什么是缓存击穿?2.2缓存击穿的解决方啊3.缓存雪崩3.1什么是缓存雪崩?3.2缓存雪崩的解决方案4.分布式锁4.1使用setnx+del实现分布式锁的添... 查看详情

redis12_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis12_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis08_缓存雪崩缓存穿透基于布隆过滤器解决缓存穿透的问题缓存击穿基于缓存击穿工作实际案例(代码片段)

文章目录①.缓存雪崩②.缓存穿透③.在centos7下布隆过滤器2种安装方式④.缓存击穿⑤.高并发的淘宝聚划算案例落地①.缓存雪崩①.问题的产生:缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至... 查看详情

redis学习笔记26——缓存异常:如何解决缓存雪崩击穿穿透问题?

缓存雪崩缓存雪崩是指大量的应用请求无法在Redis缓存中进行处理,紧接着,应用将大量请求发送到数据库层,导致数据库层的压力激增。缓存雪崩一般有两个原因导致:1、缓存中有大量数据同时过期解决方法... 查看详情

redis学习笔记26——缓存异常:如何解决缓存雪崩击穿穿透问题?

缓存雪崩缓存雪崩是指大量的应用请求无法在Redis缓存中进行处理,紧接着,应用将大量请求发送到数据库层,导致数据库层的压力激增。缓存雪崩一般有两个原因导致:1、缓存中有大量数据同时过期解决方法... 查看详情

如何解决redis缓存雪崩击穿与穿透(代码片段)

Redis最常用使用的场景就是作为业务系统的缓存,既然是作为缓存,那么就不免会碰到缓存常见的问题,即雪崩、击穿与穿透,什么是缓存雪崩、击穿与穿透以及如何解决这几个问题呢?今天我们一起来探讨一... 查看详情

redis缓存击穿(失效)缓存穿透缓存雪崩怎么解决?

...ff0c;QPS=10000左右,读写平均耗时10~100ms。用Redis作为缓存系统正好可以弥补DB的不足,「码哥」在自己的MacBookPro2019上执 查看详情

redis缓存雪崩缓存击穿缓存穿透解决方案(代码片段)

1缓存雪崩1.1发生原因(1)Redis主机挂了,Redis缓存全部失效。(2)当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。1.2解决思路(1)Redis实现高可用。(2)缓... 查看详情

redis缓存穿透击穿雪崩到底是个啥?7张图告诉你(代码片段)

目录一、缓存是什么?二、缓存的作用和成本1、缓存的作用:2、缓存的成本:三、缓存作用模型1、根据id查询数据缓存流程四、缓存更新策略1、内存淘汰2、超时剔除3、主动更新五、缓存穿透解决方法:六、缓... 查看详情

缓存击穿、穿透、雪崩及redis分布式锁

...术A分布式锁:setnx,redisson并发问题幂等问题:落表状态,Redis缓存击穿:指缓存中无,db中有原因:一个key高并发恰好失效导致大量请求到db方案:加锁,自旋锁,或一个线程查db,一个线程监控(直接用Redisson分布式锁)缓存穿透:指缓存和db中均... 查看详情