彻底搞懂Redis和Mysql如何保证数据一致性

655 阅读2分钟

本人已参与「新人创作礼」活动,一起开启掘金创作之路。

Redis的作用

一般情况下Redis是用来实现应用和数据库之间的一个读操作的缓存层,主要目的是减少数据库的io,还可以提升数据库io性能

整体架构

redis结构.jpg

  1. 命中缓存从缓存加载数据,直接返回
  2. 没有命中缓存,从数据库加载加载数据
  3. 加载到的数据写入缓存

原理

一份数据同时保存在数据库和Redis里面,当数据发生变化的时候,需要同时更新Redis和Mysql,由于更新操作是有先后顺序的,并且它并不像Mysql中的多表事务操作可以满足ACID的特性,所以就会出现数据一致性的问题,

如何保证数据一致性

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

第一种情况的缺点

20220402154659.jpg

如果先更新数据库,再更新缓存,如果缓存更新失败,就会导致数据库和Redis的数据是不一致的,

第二种情况的缺点

20220402154809.jpg

如果先删除缓存,再更新数据库,理想情况下,是应用下次访问Redis的时候,发现Redis的数据是空的那么就会从数据库加载保存到Redis里面理论上数据是一致的,但是在极端情况下,由于删除Redis和更新数据库这两个操作并不是原子操作,如果出现其它线程来访问,还是会存在数据不一致的问题

如何保证数据一致性

如果需要在极端情况下仍然去保证Redis和Mysql的数据一致性就只能采用最终一致性的一个方案

20220402154851.jpg

基于RocketMq的可靠性通信

  1. 更新数据库的数据
  2. 更新redis的数据
  3. 失败的请求写入mq事务消息
  4. 异步重试,确保成功

基于canal组件

  1. 更新数据库的数据
  2. 更新redis的数据
  3. 从binlog加载数据
  4. 同步到Redis里面

如果业务不能接受短期的不一致性,那么就不能这样的一个方案来实现