Redis——4、如何保证双写一致性

双写一致性:也就是我们在更新数据库数据的同时也要同时更新缓存中相应的数据来保证数据的一致性,避免读到脏数据。

在业务场景中我们有的业务例如转账业务是需要保证强一致性的,有的业务例如一些论坛图片的加载保证其高可用性即可。那么我们怎么去保证数据库与缓存的双写一致性来避免读到脏数据呢?

有以下两种方案:

一、延迟双删策略。

也就是我们在进行数据的写操作时,先删除缓存中的数据,接着更新数据库中的数据,然后延迟一段时间后再次删除缓存中的数据。

那为什么我们不能先删除缓存中的数据然后更新数据库接着将数据进行缓存或者先更新数据库再将缓存中的数据进行删除呢?原因是如果线程一先删除缓存中的数据,这时线程二去读缓存没读到,接着线程二就会去数据库读到脏数据返回,接着线程一才会更新数据库,这种情况是不能接受的,接着说如果我们的线程一先去更新数据库,这时线程二要进行读操作,读到了缓存中还没删除的脏数据,接着线程一才会更新缓存,这也是我们不能接受的,那么延迟双删可以在很大程度上解决这件事,但不能百分百保证,因为MySQL数据库在真实的业务场景下肯定不止一个,会要求各数据库之间的主从一致性,主数据库更新数据后,会通知数据库集群进行同时更新,但这个更新的时间是不能百分百确定的从而导致延迟双删延迟的时间是很难确定的,所以也是有读到脏数据风险的,只不过采用这种方案后,我们读到脏数据的概率会变得很小。

但我们是不推荐这种方案的因为还是有可能会读到脏数据。

二、具体的业务场景解决方案(推荐)

1、要保证业务的延迟一致性的话采用采用异步通知的方案

1)当数据需要进行写操作时,先更新数据库接着通知MQ,MQ再通知缓存进行删除操作(要保证MQ的可靠性)

2)利用阿里云的Canal,其实Canal并不用写在业务层里面,它会伪装成MySQL的从节点,当MySQL更新时,它会读取binlog日志然后对缓存进行转发通知缓存更新缓存数据操作。

2、要保证业务的强一致性时采用分布式锁的方案:

1)readlock  共享锁:当线程进行读操作的时候各线程之间是共享锁的而进行写操作时各线程之间是互斥的。

2)writelock  排他锁:线程进行数据的读写操作时是阻塞其他线程的读和写操作的。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值