DB读写分离情况下,如何解决缓存和数据库不一致性问题?

精品技术文章分享,知识的组装工


目录

  1. 前言
  2. 为什么会导致不一致
  3. 方案一:后台缓存标记法
  4. 方案二:延迟消息
  5. 方案三:更新用户再次发起读请求

前言

在 这篇文章中我们留了一个尾巴,就是在读写分离的情况下,缓存和数据库数据不一致怎么解决?

推荐大家先去看一下 这篇文章,如何解决DB数据库的数据不一致问题。

在缓存和数据库数据一致性问题中,老顾推荐是的 先更新数据库,再删除缓存。如果缓存删除失败可以用MQ消息队列的方式进行重试删除。

为什么会导致不一致

DB读写分离情况下,如何解决缓存和数据库不一致性问题?

上图流程:

1)应用服务(商品服务)请求A更新库存为99,原值为100

2)但主库同步到从库需要时间,还没有同步完成时,请求B发起读请求

3)读请求B走的是从库,取出来从库里面的旧值100

4)读请求B会把取出来的值,再设置到缓存中,值为100

5)但当从库同步数据完成,从库的数据值为99,这就导致数据库和缓存数据不一致

不知道大家看了DB读写分离导致数据不一致的问题这篇文章自己可不可以设计一个方案。老顾建议小伙伴们先自己想一下,如何设计,再往下看。

方案一:后台缓存标记法

再上篇文章【DB读写分离导致数据不一致的问题】里面提到此方案,这边就不重复介绍了,大家可以去那篇文章中查看。

数据不一致问题是因为读请求走的是从库,把从库的旧值又设置到缓存中了。后台缓存标记方案就解决了此问题,

在主从数据库同步窗口时间内,读请求也是走主库。这样就解决了读请求取到的是旧值这个问题。

但这个方案也有缺点,就是有系统性能问题,降低了吞吐量

方案二:延迟消息

其实在真实业务中,尤其互联网项目中,数据短时间的不一致时能够接受的。就像上篇文章【DB读写分离导致数据不一致的问题】中提到的本地缓存标记法,保证了本用户数据一致,其他用户可暂时不一致,但最终是一致的这个思路。我们可以设置一个延迟消息,如下图

DB读写分离情况下,如何解决缓存和数据库不一致性问题?

流程:

1)在订阅到binlog更新日志时,先不删除缓存,而是投递一个延迟消息(如:延迟10秒的消息,就是过10秒此消息才会被消费者监听到,从而被消费)

2)延迟消息的延迟时间,设置为主库与从库的数据同步延迟的时间,可自行预估

3)监听到延迟消息,在删除缓存。

这个方案的特点就是读请求会在延迟时间内读取到的是旧值,等到延迟时间一过,取到的就是新值。这个业务在互联网产品中是允许的。

如果要保证本用户(更新数据的用户)一定读到的是新值,这边可以采用本地缓存标记方案,直接从主数据库读取,读取到数据后,可以把新值设置到缓存中,这样就保证了数据一致性。

方案三:更新用户再次发起读请求

在方案二中,其他用户的读请求会有暂时间读取到的是旧值,如何缩短时间?其实是有一个方案,就是让更新用户再次发起读请求,也就是在方案二最后提到的

1)更新用户再次发起读请求,根据本地缓存标记,直接走主数据库,读取的肯定是新值,

2)再把这个新值设置到缓存中。这样就保证了缓存中的是新值,虽然从库还没有不同完成,但缓存中已经是新值了。

3)最后从库同步数据完成,值就达到了一致性

此方案的问题:就是更新操作后,多了一步读请求。

总结:小伙伴可以根据自己的业务需求,选择不同的方案,一定要结合自己的业务,没有什么完美的方案,只是如何取舍而已。


-End-

如有收获,请帮忙转发,您的鼓励是作者最大的动力,谢谢!

10几年的经验实战分享

相关微服务,分布式,高并发,高可用,企业实战,干货等原创文章正在路上

精品技术文章分享,知识的组装工


分享到:


相關文章: