Redis和MySQL如何保证数据一致性(基于最终一致性方案)


一般情况下redis是用来实现客户端应用和数据库之间的一个读操作的缓存层,主要目的是减少数据库的I/O,可以提升数据库的I/O性能(因为)。 图示 当应用需要去读取某个数据的时候,首先会尝试在Redis里去加载,如果命中了,就直接返回给客户端,如果没有命中,就直接访问数据库查询,查询到数据之后再把数据缓存到Redis里面。

使用Redis作为缓存的架构

问题:

在这样的架构里面会出现一个问题,就是一份数据同时保存到MySQL到Redis里面,当数据发生变化的时候,需要同时去更新Redis和MySQL。

由于更新操作是有先后顺序的,并且它并不像MySQL中的多表事务操作那样可以满足ACID的特性,所以就会出现数据一致性的问题

如何解决?

常见解决数据一致性的4种方法.

  • 1、先更新数据库,再更新缓存
  • 2、先删除缓存,再更新数据库
  • 3、基于RocketMQ的可靠性消息通信
  • 4、

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

先更新数据库,再更新缓存 在使用该方案时,如果缓存更新失败就会导致数据库和Redis的数据是不一致的。

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

先删除缓存,再更新数据库 在使用该方案时,理想情况下,是客户端应用下次访问Redis的时候发现Redis的数据是空的,那么就会从数据卷加载,从而保存到redis里面,也就是说数据理论上是一致的。但是在极端情况下,由于删除Redis和更新数据库这2个操作并不是原子操作,所以在这个过程中出现了其他线程来访问。依旧会出现数据不一致的问题。所以如果要在极端情况下仍然去保证Redis和MySQL的数据一致性。就只能采用最终一致性的方案

基于RocketMQ的可靠性消息通信

基于RocketMQ的可靠性消息通信 可以通过基于RocketMQ的可靠性消息通信,来实现数据的最终一致性。

Canal组件监控MySQL的binlog日志

监控MySQL的binlog日志 通过Canal组件监控MySQL的binlog日志,把更新后的数据同步到Redis里面。

总结:

这是基于最终一致性来实现的,如果业务场景不能去接受数据的短期不一致性那么就不能使用这样的一个方案。


分类:Redis
标签: Unsafe
文章目录