Redis与MySQL数据库数据一致性方案

一致性方案的设计原则

  • 数据一致性:确保Redis和MySQL中的数据在任何时候都是一致的,即任何对数据的修改在Redis和MySQL中都应同步体现
  • 事务性:确保数据同步操作具有原子性,即要么全部成功,要么全部失败。
  • 持久性:确保即使系统崩溃或重启,已同步的数据也不会丢失。

实现方案

设置缓存key过期时间

  • 此方案只适用对数据一致性要求很低或写请求很少的业务,当查询没有命中缓存时,就从数据库中读,把查到的数据写到缓存,同时设置缓存的过期时间。
  • 写操作直接更改数据库,不用更新缓存。但是当一个key没过期时,写操作已更新数据库数据,此时的读还是读取到旧数据。此时就出现数据不一致了。

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

  • 此方案适用于读多写少的场景。但是可能会出现更新完数据库还未更新缓存,此时的查询操作查询缓存则是更新之前的数据,就会造成数据不一致了

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

  • 先删除缓存,如果删除成功再去更新数据库,就算数据库更新失败,再次读取数据库缓存到redis数据还是一致的。
  • 但是高并发的情况下,如果A删除完缓存,A再去更新数据库,在更新的过程后,B来查询数据,发现缓存没有,就从数据库获取并更新缓存,后面A更新成功,就会出现缓存和数据库不一致。如果后面一直没有更新操作,则缓存则与数据库一直不一致了,所以这种情况给缓存设置一个过期时间,做一个兜底操作

延时双删

  • 先删除缓存数据,再更新数据库数据,等待一小段时间,再次删除缓存数据(可以另开线程执行删除,也可以设置删除重试次数,避免删除失败)
  • 存在的问题:无法绝对保障数据的一致性,因为延迟时间难以确认,如果偏大也会造成系统性能问题,所以到底是延迟多长时间,这个很难确认,偏小又起不到延时双删的作用。所以延时时间还得根据实际场景做出评估。

使用消息队列

  • 先更新数据库,然后将删除缓存的消息投递到消息队列中。收到删除缓存消息后,尝试进行删除缓存。如果失败,则不断进行重试。
  • 引入了消息队列,系统的复杂性提升,可用性降低。也会带来各种各样的问题,例如消息丢失、乱序与重复消费等。在删除缓存的场景下,乱序与重复消费不会造成任何问题。但是消息丢失则会导致数据不一致情况。

监听binlog

  • 异步监听binlog:监听数据库的binlog,检测到数据更新则去删除缓存,如果删除失败则通过MQ不断重试,直至删除成功,业务代码只操作数据库,不操作缓存。同时启动一个订阅binlog的程序去监听删除操作,然后投递到消息队列中。再启动一个消费者,根据消息去删除缓存。在MySQL中,可以使用Canal中间件来订阅binlog。
  • 该方案使用一个中间件来帮我们完成解耦工作,但也让系统的复杂度逐步上升。

总结

大量数据同步可能导致Redis和MySQL的性能下降,也会增加系统的复杂性,维护成本也会上升,在选择方案时要针对自己的业务场景选择合适的方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值