缓存与数据库一致性:问题总结

请先了解旁路模式延迟双删的正常流程。再考虑不正常的情况。否则容易混。

  • Cache Aside Pattern(旁路缓存模式)

        更新请求  :更新数据库 -> 删除缓存

        读取请求 : 读取缓存 -> 读取mysql ->写入缓存

不正常的问题:

- 更新和删除 的倒序情况:

        1. 读取请求倒序不能倒序! 一定要 先 读取缓冲 的!不然加缓存有什么用!

        2. 更新请求倒序:如果先删除缓存,再更新数据库的问题:

               查询+更新 的异常情况:

线程A (更新操作)

线程B(查询操作)

删除缓存 (num = 1)

缓存查不到

去数据库查询 (num = 1)

更新数据库(num = 2)

写入缓存(num = 1)

               更新+更新的异常情况

                没什么问题!

- 先更新数据 再删除缓存一定没问题吗?

                更新+查询

线程A(更新操作)

线程B(查询操作)

缓存查不到

去mysql查(num = 1)

更新数据库(num=2)

删除缓存

写入缓存(num=1)

                更新+更新

                没什么问题!

那既然旁路模式 是有问题的,为什么 我们还要使用?

这个在实际当中发生的概率很小。为什么?

因为缓存的写入通常要远远快于数据库的写入,所以实际当中,很少会出现请求B将数据库更新并且删除缓存后,请求A才写回缓存的情况。


延迟双删

        读策略:读取缓存 - > 未命中 读取mysql ->写入缓存

        写策略:删除缓存 -> 更新数据库 - > 延时sleep -> 删除缓存

那么为什么要延迟一会呢?

如果不延迟的话:

线程A (更新操作)

线程B(查询操作)

删除缓存 (num = 1)

缓存查不到

去数据库查询 (num = 1)

更新数据库(num = 2)

sleep

删除缓存

写入缓存(num = 1)

对吧,另一个查询操作的写入缓存操作 会跑到 更新操作的删除之后!所以需要延时双删。

为什么要先删一次呢?

这个我本人的理解,如有更合理的理解欢迎留言!😀🙏🙏)

线程A (更新操作)

线程B(查询操作)

删除缓存 (num = 1)

缓存查不到

去数据库查询 (num = 1)

更新数据库(num = 2)

写入缓存(num = 1)

sleep

删除缓存

       大部分的时候可以提前保证一致性。

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值