redis和mysql数据不一致_高并发下为什么 redis 和数据库不一致?怎么解决?

现在的web架构一般都用redis作为缓存层来减轻数据库的压力,数据在此架构下的读取问题,一般都是先判断redis缓存是否有数据,如果有,直接返回,否则读取数据库的数据,写入redis,返回数据,这是大致的读取流程。

那么为什么会出现redis和数据库不一致的问题呢?举个例子,如果你的缓存里现在缓存了用户的年龄的数据,每次用户访问的时候,如果缓存里有这个数据,直接返回,那么如果用户更新了自己的年龄,你的操作步骤是什么?

先更新(删除)redis缓存,再更新数据库

先更新数据库,再更新(删除)用户缓存

上面两种不同的操作顺序,不论哪种方法,理论上如果两个步骤都成功了,那没问题,如果一个更新成功了,另一个更新失败了,那么就会导致数据库和缓存不一致的问题,这就要求操作必须具备原子性,不论谁先执行,只要一个步骤出现错误,就因该回滚,谁都不能成功。

更新缓存or删除缓存

这里简单说下,更新缓存可能要消耗更多的cpu资源,所以建议直接删除缓存。

举个例子:缓存money=100,数据库money=100,现在要求money=99

下面讨论并发下两种策略可能带来的问题

先删除缓存成功,后更新数据库失败

线程A删除缓存,更新数据库money中,还没更新完

线程B过来发现缓存没有了,去数据库读取,读到的money=100

线程B,将读到的money=100写入缓存,现在缓存中的money=100

线程A将数据库的money更新完成,money=99

最终redis缓存的数据是100,数据库是99

适合原子性要求高的,不适合高并发

造成这个问题的原因就是线程A还没干完事情,线程B就插进来了。解决这个问题的办法,就是串行化,让操作顺序执行,不能交替进行。顺序应该是删除、更新、读取。

先更新数据库,再删除缓存

线程A过来查数据,缓存没有数据,读取数据库money=100

线程B更新数据库money=99,并删除缓存

线程A把读到的money=100,写到缓存里

最终redis缓存是100,数据库是99

适合高并发,不适合原子性高的

造成这个问题的原因就是第二步骤,其实缓存并不存在,删除是没有用的,应该等到A把缓存写入之后,再尝试删除缓存,这时候建议再第二步骤一直尝试删除缓存,知道删除成功。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值