一架梯子,一头程序猿,仰望星空!
Redis面试题 > 内容正文

怎么保证redis与Mysql的数据一致性?


问题简答

为了保证Redis和MySQL数据一致性,可以采用MySQL和Redis双写、主动删除或者更新Redis数据策略、通过binlog异步更新Redis等方案。

问题详解:

1.实时更新

提示:下面的方案,都不能完全确保数据一致性,只能说根据业务场景够用就好。

1.1.先写MySQL,再写Redis(双写)

  • 复杂的业务场景,主动更新Redis的成本比较高,需要构造出复杂的缓存数据。
  • 并发更新数据的情况下,可能会出现Redis数据不一致情况,出现脏数据,需要额外控制双写事务的顺序。

1.2.先写Redis,再写MySQL(双写)

  • 优点:因为先更新redis数据,有利于高并发情况下,直接从Redis读取数据。
  • 缺点:存在MySQL宕机时,数据不一致的风险,因为还没来得及更新MYSQL数据,其他缺点跟1.1一样。

1.3.先写MySQL,再删Redis

  • 优点:确保数据一致性,实现简单,也是目前主流的方案,因为不需要主动更新redis数据,直接删除redis key即可。
  • 缺点:可能出现数据不一致,例如: redis挂了,或者MYSQL新的数据还没有来及同步到从库,都可能导致Redis缓存的数据是老数据。

1.4.先删Redis,再写MySQL

  • 优点:相对于1.3方案没啥优点
  • 缺点:还是数据不一致,先删除redis,mysql还没来得及更新,redis缓存的数据还是老数据。

1.5.延时双删

主要是弥补1.3方案,在集群模式下(MYSQL主从架构),数据同步延迟导致的不一致问题。
例如:先更新MYSQL,删除Redis数据,这个时候,如果MYSQL数据还没有来得及同步到从库,Redis从MYSQL从库读取数据,就会导致数据不一致。

延时双删策略:先删除Redis,写MYSQL,延迟一会(等MYSQL数据同步)再删除Redis

2.异步更新

对实时性要求没那么高,可以采用基于消息队列和mysql binlog订阅的方式,异步更新redis数据(删除key或者主动更新数据)