浅谈一下Redis缓存失效问题

文章介绍了缓存中的三大问题——缓存穿透、缓存击穿和缓存雪崩,以及对应的解决方案。缓存穿透可通过缓存null结果和使用布隆过滤器避免;缓存击穿可采用设置永不过期或加锁机制解决;缓存雪崩则建议使用随机过期时间和加锁。对于缓存和数据库一致性,双写策略可能存在并发问题,而延迟双删更为常见。此外,分布式锁是解决高并发场景下的关键工具。

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

1.缓存穿透、缓存击穿、缓存雪崩解决方案

缓存穿透

查询一个不存在的数据,100万条请求去查,结果缓存里面没有,都走了数据库。

解决方案:

1.缓存一个null的结果在缓存

2.布隆过滤器

缓存击穿

某一个热点数据,当它缓存失效的一瞬间,进来了大量请求,此时这些请求都去走了数据库,导致数据库压力过大崩溃了。

解决方案:

1.热点key设置永不过期(不推荐)。

2.加互斥锁,加锁保证只有拿到锁的请求,能够执行查询数据库,其他未拿到锁的请求进入阻塞等待状态。

缓存雪崩

当缓存大面积同时失效,这时候大量请求都走了数据库。缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key。

解决方案:

设置缓存的时候过期时间不要用同一个,在一定时间的基础上加一个随机数,保证不会在同一时间大量失效。

2.如何保证缓存和数据库的一致性

1)双写

当修改数据的时候,同时更新数据库以及缓存的数据,并且一定要是在同一把锁中。
存在问题:
1.双写过程中发生异常,就有可能发生数据库更新了,缓存未更新;或者缓存更新了,数据库没更新。
2.并发问题,如两个并发请求A、B这种情况。A更新数据库,B更新数据库,B更新缓存,A更新缓存,这种情况就会导致B更新的缓存内容丢失了。所以说双写的过程需要加锁。

2)更新后删除缓存(比双写要好一点)

每当修改了数据时,把该数据在缓存里面的也删除了。这样下次请求来的时候,会去数据库查一次最新的数据,然后重新放入缓存中。
延迟双删:更新了数据库以后,往消息队列里面添加一条消息,等待一定时间后删除缓存。

总结下来:两个方法其实都不能保证强一致性。如果真要保证的话只能够牺牲性能来解决,加悲观锁等等。大多数情况下使用延迟双删策略。

3.分布式锁

在分布式系统下,本地锁满足不了分布式系统的场景,本地锁只适用单体项目,由此引出了分布式锁。
原理:setnx 写入一个key如果不存在就写入,存在返回null,利用redis的这个命令,实现占坑的目的。高并发场景下,大量的请求进来,只有拿到锁的请求才能够执行后续代码,执行完毕后,需要释放锁。没拿到的可以一直自旋等待,直到获取到锁。比如我们的抢票啊,约课等场景。
流程:加锁保证原子性,解锁保证原子性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值