缓存数据和数据库一致性实现策略

缓存正常使用流程

读流程

  1. 程序首先首先查询缓存是否存在目标数据,有则返回,也称缓存命中;否则转第二步
  2. 查询数据库
  3. 将查询到的数据更新缓存,并将数据返回给应用程序
    如下图所示:
    在这里插入图片描述

写流程

当涉及缓存中的数据更新的时候,可以有多种更新策略:

1. 先更新数据库,再更新缓存

存在问题:由于并发操作的存在,假如有两个线程T1,T2都来更新同一条数据,操作顺序如下:
1.T1更新数据库成功
2.T2更新数据库成功
3.T2更新缓存成功
4.T1更新缓存成功
那么,缓存中数据应该和数据库中最新的数据T2更新后保持的一致,但是现在缓存中却是T1更新后的数据,出现了缓存数据和数据库不一致

2. 先更新缓存,再更新数据库

存在问题:情况和先更新数据库,再更新缓存一样,发生不一致

3. 先更新数据库,再删除缓存(优选)

存在问题:假如某个缓存数据在某个时刻刚好过期,这时有两个线程T1,T2,T1获取数据,T2更新数据,操作顺序如下:
1.T1查询缓存未查询到数据
2.T1查询数据库
3.T2更新数据库成功
4.T2删除缓存
5.T1将数据放入缓存中
出现了缓存和数据库数据不一致,因为缓存的是旧数据。但是出现这种情况的概率太小了,因为在T1查询到数据库数据准备放入缓存期间,T2更新数据库同时删除缓存,这两步操作,是要花一定时间的,相对T1把数据库放入缓存这个时间,还是相当大的,数据库操作是个比较耗时的操作。所以优选这种策略。还可以采取进一步的措施,在T2更新数据库成功后,让T2睡眠一段时间,让T2的删除缓存操作在 T1更新缓存之后,这样只出现短暂的不一致情况,至于睡眠时间的选择,可以设置为一次数据数据库查询时间+缓存更新的时间之和。

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

存在问题:假如两个线程T1,T2,T1读取数据,T2更新数据,操作顺序如下:
1.T2删除缓存
2.T1查询缓存未查询到数据
3.T1查询数据库
4.T1将数据放入缓存中
5.T2更新数据库成功
那么,缓存中将是旧的数据,出现缓存数据不一致

缓存数据和数据库一致性实现策略选择

1.数据库单节点场景

数据库是单节点部署的情况下,选择:先更新数据库,再删除缓存,虽然改策略也有瑕疵,但是概率极小。当然若是反生删除失败,也以采取将删除操作放入消息队列中,通过消费消息来删除redis数据,直到删除成功为止,再加上队列的监控,监控删不掉的情况。

2.主从模式场景

由于主从模式,存在数据复制延迟的情况,假如更新数据库(主库)成功,然后删除缓存,后面查询缓存未命中,查询数据库查的是从库,缓存的是旧的数据,也会发生缓存和数据库数据不一致的情况。对于mysql,可以订阅binlog日志,可用用阿里在这里插入图片描述
canel框架,将binlog日志数据解析,放到消息队列,消息消息队列更新缓存即可。程序实现结构图如下(引用他人的):

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值