【redis】mysql与redis数据一致性问题

在数据库更新后,如何确保Redis缓存的一致性是一大挑战。文章讨论了不同一致性要求下的解决方案,包括普通缓存、热点key的处理、内存数据库场景以及利用MySQL binlog和MQ实现最终一致性。同时,提出了异步线程更新和后台检查的方法来降低数据不一致的影响。

在增删改数据后,我们往往需要删除旧缓存,以生成新的缓存,但是redis和mysql无论谁先执行都不能保障另一个会失败,所以会出现不一致问题。

首先需要确定的是,由于网络等各种原因的限制,mysql与redis数据是不可能保持强一致性的,就算是单机、mysql加锁、串行化执行都不能保证强一致性。通常我们所说的一致性需要根据业务场景综合分析对策。

个人认为一致性的要求分为“时效性”和“准确性”两方面。

时效性:mysql更新后redis尽快删除。

准确性:mysql更新后redis也要删除,尽可能减少更新的丢失。

普通缓存

时效性和准确性要求都并不高,即使某次redis删除失败也没大的影响,无需特殊处理,要求较高时可以适当缩短缓存时长。

热点key、更新极少的key

时效性要求可以稍微低一点,但是准确性要求较高,可以获取redis删除结果,删除失败可以放入MQ。

删除成功并不能保障真的成功,因为redis异步确认的特点,有可能是在故障转移期间先答复客户端成功但实际没成功。

通常热点key能接受这种概率,如果不能就需要像内存数据库这样加上定时任务去增量和全量比对redis和mysql。

内存数据库

如果是读多而写特别少的场景,缓存时长通常更长,甚至写过一次就长期有效作为内存数据库使用或者作为系统设置,此时缓存准确性要求会很高。

数据库日志分析+MQ

通过binlog工具如canal等监测mysql的binlog,再把监测到的更新通过MQ推送到redis服务器进行消费,实时性较高,且MQ大都支持重投、重试等,可以保障redis最终能和mysql保持一致。

Canal的部署支持集群,需要配合ZooKeeper进行集群管理。

参考:

https://blog.youkuaiyun.com/yehongzhi1994/article/details/107880162

https://blog.youkuaiyun.com/yehongzhi1994/article/details/108034330

异步线程更新

一种开销比较小的方式是,定时比如每五分钟对指定数据表五分钟内的数据进行扫描,和redis中数据进行对照,每天凌晨在redis中对前一天mysql的更新进行检查,这种更适合redis做内存数据库并且可以容忍一段时间内数据不一致的情况。

直观展示

如后台设置,需要用到redis时可以直接查看mysql、redis的值,一旦真的不一样可以手动修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值