缓存与数据库的数据一致性问题

首先,我们要知道为什么会引发数据不一致的问题?

读写流程:
写流程:
(1)先淘汰cache
(2)再写db
读流程:
(1)先读cache,如果数据命中hit则返回
(2)如果数据未命中miss则读db
(3)将db中读取出来的数据入缓存
我们要放入缓存前,会先读取数据库的数据,再将其放入缓存中。
数据不一致在于:我们在线程A读数据库数据并将其放入缓存中的时候,同时有一个线程B去操作数据,对数据进行了改变。这时候,线程B还没有成功改变数据,我们的A线程已经将数据读入缓存中了,缓存中的是旧数据,这就是数据不一致。

在分布式环境下,数据的读写都是并发的,上游有多个应用,通过一个服务的多个部署(为了保证可用性,一定是部署多份的),对同一个数据进行读写,在数据库层面并发的读写并不能保证完成顺序,也就是说后发出的读请求很可能先完成(读出脏数据):
在这里插入图片描述

(a)发生了写请求A,A的第一步淘汰了cache(如上图中的1)
(b)A的第二步写数据库,发出修改请求(如上图中的2)
(c)发生了读请求B,B的第一步读取cache,发现cache中是空的(如上图中的步骤3)
(d)B的第二步读取数据库,发出读取请求,此时A的第二步写数据还没完成,读出了一个脏数据放入cache(如上图中的步骤4)
即在数据库层面,后发出的请求4比先发出的请求2先完成了,读出了脏数据,脏数据又入了缓存,缓存与数据库中的数据不一致出现了。

我们去查询数据的时候,就会先读缓存,我们读到的是旧的数据,而数据在数据库中已经改变了。

怎样解决这个问题呢?

我们首先,要想让缓存中的数据是最新的,也就是保证我们读到的就是最新的数据,我们要让读写操作串行化
读写数据库的时候,会先获得数据库连接,我们要保证,读写的操作使用同一个连接,让先写,再读就保证读到的是最新的数据。
怎样保障使用同一个链接?
根据你要查询的数据,比如根据用户id去查询何改变数据,我们获得连接时,将这个userid传入。读写传入的都是同一个userid,获得的也是同一个连接。这是在数据库层面的解决一致性问题。
缺点也很明显:效率变低,吞吐量减少。

因此,如果我们的系统不是要求缓存与数据库必须保证强一致性的话,我们进行读操作读出旧数据也没事,写操作的时候,先更改数据,再删除缓存,但是,我们不将更改后的数据放入缓存中,等待有人去进行读操作的时候,再放入缓存中。我们只要保证数据最终一致就好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值