redis和数据库的缓存一致性问题

数据库和缓存如何保证一致性

  1. (实际采用)先更新数据库,成功后,再删除(失效)缓存:并发问题:比如,缓存中的数据刚好失效,导致读请求去数据库中读取了数据,而此时写操作更新了数据库,成功后又删除了缓存,但前面的那个读请求又将之前读取的旧数据存到了缓存,从而导致缓存中是脏数据了。。但这种情况实际出现的概率很低,因为这个条件需要发生在读缓存时缓存失效,而且并发着有一个数据库的写操作,同时读操作在写操作前进入数据库,而又要晚于写操作更新缓存。但实际上数据库的写操作会比读操作慢得多(写操作会加锁),所以这些条件都具备的概率很小。可以采用过期失效的方式来解决,就是设置过期时间,到期后缓存失效,载入最新的数据,但需要系统能够容忍一段时间的数据不一致。(对于实时性要求很高的数据,可以将数据放在数据库中,而不放到缓存里。数据库中的数据进行修改时会给数据加上写锁,于是可以避免缓存场景中的数据不一致问题。)
  • 更新数据库成功,删除缓存失败怎么办?
    • 将想要删除的key放进消息队列,消息队列的消费端收到这个key时就执行删除缓存中对应key的操作, 并设置失败重试(消息队列的请求确认机制),超过最大重试次数(比如5次)后就报警给运维人员。
  1. 先更新数据库,后更新缓存:在并发情况下会存在多线程 写缓存 造成脏数据的问题:假设A、B两个线程,A先更新数据库,B后更新数据库,然后AB分别更新缓存,但是B先更新缓存成功,A后更新缓存成功,这样就导致数据库是最新的数据但缓存中是旧的脏数据。而如果删除缓存数据的话,可以保证下一次读请求回源到数据库,将最新的数据载入到缓存中,避免脏数据的问题。因此,针对数据更新缓存,采用删除缓存的方式进行处理。

  2. 先删除缓存,再更新数据库:并发问题:删除缓存后,查询操作没有命中缓存,会把老数据读出来后放到缓存中,然后更新操作才去更新数据库。于是,在缓存中的数据还是旧数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。

不能用事务

  • 如果将更新数据库和删除缓存放到一个事务中,如果操作很耗时的话,就会造成大量的数据库连接挂起,严重降低系统的性能。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值