缓存击穿、缓存穿透,缓存雪崩的定义及其解决方案

本文详细探讨了缓存中的三大问题:缓存击穿、缓存穿透和缓存雪崩,以及相应的解决方案。对于缓存击穿,提出了数据不过期和使用互斥锁的方法;缓存穿透的处理包括使用布隆过滤器、异步更新和设置空值缓存;而缓存雪崩的预防措施包括随机过期时间、双缓存策略和互斥锁。这些策略旨在确保系统的稳定性和数据库的安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,我们来看下是如何获取到的数据:当接收到用户请求,首先尝试从Redis缓存中获取到数据,如果缓存中获取到数据则直接返回结果,若缓存中不存在数据时则从数据库中获取数据,如果数据库获取数据成功,则更新Redis然后返回数据。获取数据流程图

  • 缓存击穿

定义:高并发的情况下,某个热门key突然过期,导致大量请求无法在Redis中获取到缓存数据,进而全部访问数据库,引起数据库瞬间压力增大。

解决方案:缓存击穿的情况下一般不容易造成数据库的宕机,只是会造成对数据库的周期性压力增大。对缓存击穿的解决方法一般可以这样:

1.Redis中的数据不设置过期时间,然后在缓存的对象上添加一个属性标识过期时间,每次获取到数据时,校验对象中的过期时间属性,如果数据即将过期,则异步发起一个线程主动更新缓存中的数据。但是这种方案可能会导致有些请求会拿到过期的数据,就得看业务是否可以接受。
2.如果要求数据必须是新数据,则将热点数据设置成永不过期,然后加一个互斥锁保证缓存的单线程写入。

  • 缓存穿透

定义:是指查询缓存和数据库中都不存在的数据。比如通过id查询商品信息,id一般是大于等于0的值,恶意攻击者故意传id为小于0的值去查询,由于Redis缓存是不命中的则从数据库中获取数据,这将会导致每次缓存都不命中数据导致每个请求都访问数据库,造成缓存穿透。

解决方案:
1.利用互斥锁,缓存失效的时候,先获得锁,得到锁后,再去请求数据库。没得到锁,则休眠一段时间再尝试。
2.采用异步更新策略,无论key是否获取到数据,都直接返回。数据中维护一个缓存失效时间,缓存如果过期,异步发起一个线程去读数据库,更新缓存。需要做好缓存预热(项目启动前,先加载缓存)操作。
3.提供一个能迅速判断请求是否有效的拦截机制。比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速做出判断,请求所携带的key是否合法有效。如果不合法,则直接返回。
4.如果从数据库中查询的对象为空,也放入缓存中。只是设定的缓存过期时间较短,比如设置为30秒,60秒等。

  • 缓存雪崩

定义:缓存中如果大量缓存数据在一段时间内集中过期,这时候会发生大量的缓存击穿现象。所有的请求都落在了数据库上,由于查询数据量巨大,引起数据库压力过大甚至导致数据库的宕机。

解决方案:
1.给缓存的失效时间,加上一个随机值,避免集体失效。如果Redis是集群部署的话,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题。
2.使用互斥锁,但是该方案吞吐量明显下降
3.设置热点数据永不过期
4.双缓存。设置两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设置失效时间。自己做缓存预热操作。然后细分以下几个小点:
(1)从缓存A读取数据库,有则直接返回。
(2)缓存A没有数据,直接从缓存B中读取数据,直接返回,并且异步启动一个更新线程。
(3)更新线程同时更新缓存A和缓存B

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值