缓存与数据库一致性

1、先更新缓存,后更新数据库

第二步失败,则在缓存失效之前读取的都是旧数据。

2、先更新数据库,后更新缓存

第二步失败,缓存失效后读取到的都是错误的数据。

缓存利用率角度看:

  • 每次数据变更都更新缓存,但缓存可能长时间不被访问,浪费资源。

  • 很多情况下缓存中的值与数据库不是一一对应的,可能是数据库的资源经过一系列计算得出的值。

3、先删除缓存,再更新数据库(实际有一定使用量)

第二步失败问题,读取到的都是旧数据。

并发问题,线程A执行操作时,线程B在删除缓存后更新数据库前查询数据,查到旧数据——>缓存延迟双删:删除缓存,更新数据库,删除缓存。延迟时间在分布式和高并发场景下很难评估,很多时候,我们都是凭借经验大致估算这个延迟时间,例如延迟 1-5s,只能尽可能地降低不一致的概率。

4、先更新数据库,再删除缓存(比较流行)

第二步失败,缓存失效之前读取的都是旧数据。

并发问题,缓存中不存在时A读取数据库得到旧值,B更新数据库并删除缓存,A将旧值写入缓存。(概率很低)

应对第二步删除缓存失败方法

1、异步重试:把操作缓存这一步,直接放到消息队列中,由消费者来操作缓存。(消息队列保证可靠性)

2、订阅数据库变更日志,再操作缓存:用 canal(阿里)监听binlog日志去进行同步数据。(可以做数据同步)

引入消息队列等其他组件,增加系统复杂度。

其他思考:

引入缓存的目的就是为了性能,性能和一致性就像天平的两端,无法做到都满足要求。当操作数据库和缓存完成之前,只要有其它请求可以进来,都有可能查到「中间状态」的数据。如果非要追求强一致,那必须要求所有更新操作完成之前期间,不能有「任何请求」进来。虽然我们可以通过加「分布锁」的方式来实现,但我们要付出的代价,很可能会超过引入缓存带来的性能提升。

个人觉得引入缓存之后,有些场景如果为了短时间的不一致性问题,选择让系统设计变得更加复杂的话,完全没必要。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值