如何保证redis和数据库的一致性

在项目中难免会使用到redis作为缓存,去减轻数据库的访问压力,但是涉及到数据更新时,如果redis和数据库的操作设计出现问题,就会导致redis缓存中和数据库中的数据不一致的情况。那么我们如何去保证缓存与数据库中数据一致呢?

四种同步策略
想要保证缓存与数据库的双写一致,一共有四种方式,即四种同步策略
1、先更新缓存,再更新数据库
2、先更新数据库,再更新缓存
3、先删除缓存,在更新数据库
4、先更新数据库,再删除缓存

更新缓存和删除缓存的选择
更新缓存

优点:
如果每次数据变化都能被及时更新,那么查询数据时不容易出现不命中的情况,
缺点:
1、如果数据的计算复杂,频繁的更新会造成服务器性能的消耗比较大
2、如果数据并不是被频繁使用,那么频繁更新也只是浪费服务器性能,对业务没有多大的帮助
适用于数据使用较为频繁,且数据的计算不那么复杂的场景

删除缓存

优点:不需要顾忌数据的复杂性,直接删除即可
缺点:查询数据时,增大未命中的几率,从而增大数据库的访问压力
适用于数据使用频率不高的场景

在上面四种同步策略中,都存在导致数据不一致的风险

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


操作步骤:
a、线程A删除缓存中的数据,
b、线程A更新数据库中的数据,但是更新失败
c、此时线程B去获取缓存中的数据,但是未命中
d、线程B,去数据库中获取数据,但此时的数据因为更新失败为旧数据
e、线程B将数据库中查到的数据同步到缓存中去
f、线程A此时更新数据到数据库成功
最后数据库和redis缓存中的数据不一致

如果在更新数据库时没有出现失败,也同样存在会造成数据不一致的情况

操作步骤:
a、线程A删除缓存中的数据,
b、此时线程B去获取缓存中的数据,但是未命中
c、线程B,去数据库中获取数据,但此时的数据因为更新失败为旧数据
d、线程B将数据库中查到的数据同步到缓存中去
e、线程A此时更新数据到数据库成功
最后数据库和redis缓存中的数据不一致,这里造成的数据不一致的原因是线程B在数据库还未更新时就已经获取到了旧的数据。

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

操作步骤:
1、线程A更新数据库中的数据
2、线程A删除缓存中的数据,删除失败
3、线程B查询缓存中的数据,查询到旧数据
4、线程A异步重试删除缓存
这里,删除缓存中数据失败后就会造成线程B获取到缓存中的旧数据,从而导致数据不一致的情况

如果缓存没有删除失败的情况也可能导致数据不一致

操作步骤:
1、线程A更新数据库中的数据
2、线程B查询缓存中的数据,查询到旧数据
3、线程A删除缓存
如果线程B在缓存删除前获取到了缓存中的数据,那么线程B获取到的还是旧数据,也会导致数据不一致的情况

延时双删
上面中先删除缓存,在更新数据库在不出现失败时也会出现数据不一致的情况,那么我们要有什么解决方案呢。我们就采用延时双删的策略来保证缓存中的数据时更新后的数据
操作步骤
1、先删除缓存
2、更新数据库
3、线程等待 N秒(等待时间根据具体业务来判断)
4、再删除缓存
这样就保证了缓存中的数据最终会和数据库中的数据保持一致

异步更新缓存(redis订阅binlog的同步日志)
1、更新数据库
2、生成binlog增量消费日志,
3、推送binlog日志到消息队列中
4、根据binlog日志对redis进行数据更新

数据读取:从redis中读取热点数据
数据更新:将数据更新到数据库中
数据同步:根据binlog日志,将数据同步到redis中

增量:对数据的增删改。

当数据发生增删改的操作时,先将数据在数据库中进行增量操作,并把binlog日志推送给消息中间件,订阅过的redis或者会接收到对于的binlog消息,redis根据binlog日志的内容对数据进行增量操作,这类似mysql的主从备份,利用binlog日志达到数据一致性的目的
————————————————
版权声明:本文为CSDN博主「可乐丿不加冰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44740485/article/details/124846964

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值