mysql读写分离 保持数据一致性_如何保持Redis和db的数据一致性

导致数据不一致性的场景:

场景一(查询):

高并发的时候,线程A redis未命中,去查询db,得到值1,还未回种redis,这时候db修改了,线程B redis未命中,查询db,得到值2,但线程B先存入redis,然后线程A存入redis,这时候redis的数据是值1,是条脏数据。

解决方案:

通过加锁解决,保证查询db和存入redis操作的原子性,或者用乐观锁,加个版本号或者时间戳,存入redis之前查下,但还是要保证查和存的原子性

场景二(更新):

先写入db,在删除缓存,可能出现db已经更新,但redis中未更新的情况,这时候redis命中后查到的数据就是旧数据,所以不行。

场景三(更新):

先删除缓存,再写入db。这其实也有并发问题:线程A是更新操作,先删除缓存,但还没写入db,这时候线程B来了,是个查询操作,发现缓存中没有数据,就去查db,但这时候线程A的写入操作还没完成,于是线程B查到了脏数据。

解决方案:

老外提出了一个缓存更新套路,名为Cache-Aside pattern。其中就指出

失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。

命中:应用程序从cache中取数据,取到后返回。

更新:先把数据存到数据库中,成功后,再让缓存失效。

这样的策略其实还是会出现并发问题:

假设这会有两个请求,一个请求A做查询操作,一个请求B做更新操作,那么会有如下情形产生

(1)缓存刚好失效

(2)请求A查询数据库,得一个旧值

(3)请求B将新值写入数据库

(4)请求B删除缓存

(5)请求A将查到的旧值写入缓存

此时,产生脏数据的原因:

请求B的写操作(3)要比请求A(2)的读操作耗时更短,才会出现(4)先于(5)

但是出现该情况的可能性是有多大呢,这边以读写分离为例,为啥会出现读写分离,读写分离的意义就是因为读操作比较快,耗资源少,不然要读写分离干啥?所以出现该场景的可能性太小了。

总结

redis和db的数据一致性理论上是不可能,如果真的对数据有强一致性的要求,就不应该放缓存里!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值