Redis和Mysql如何保证数据一致性
都依凡
撰写于 2023年 05月 27 日

Redis和Mysql如何保证数据一致性

1. 导致数据不一致的原因

当数据发生变化的时候,需要同时去更新Redis和Mysql,更新数据是有先后顺序的,在极端情况下就会出现数据一致性的问题。

1. 先更新数据库再更新缓存

如果先更新数据库,若是缓存中的数据更新失败,就会出现数据库和redis中的数据不一致问题

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

先删除缓存再更新数据库,在理想情况删除了缓存,更新了数据库,再第二次请求的时候会发现缓存是空的,会去读取数据库将数据缓存起来。

但是

删除缓存和更新数据库不是一个原子操作,若是缓存删除了,此时,第二条线程抢到CPU时间轮片,开始读取数据,发现没有缓存,查询数据库,并将数据缓存起来,此时第一条线程拿到CPU时间轮片,开始更新数据库,这个情况下会导致数据库和缓存不一致

采用最终一致性的方案解决

1. 采用延迟双删除的策略

具体步骤

  1. 先删除缓存
  2. 写入数据库
  3. 休眠500毫秒(视情况而定)
  4. 再次删除缓存

具体实现

public void write(String key,Object data){
     redis.delKey(key); // 删除缓存
     db.updateData(data); // 更新数据库
     Thread.sleep(500); // 睡眠延迟
     redis.delKey(key);// 再次删除缓存
 }

2. 异步更新缓存(基于订阅Binlog)

读取MysqlBinlog日志后分析,利用消息队列,推送更新到redis缓存中,这样一旦产生了新的写入,更新,删除等操作,就可以把相关的更新推送到redis中

其实这种机制类似于Mysql的主从备份,Mysql的主从备份也是通过Binlog来实现数据一致性
这里的消息推送工具可以使用Kafka、rabbitMQ等消息队列来实现

结合使用canal(阿里的一款开源框架),通过该框架可以对MySQL的binlog进行订阅

因为是最终一致性,所以业务如果无法接收短期不一致性的话就得更换策略

Redis和Mysql如何保证数据一致性

Redis和Mysql如何保证数据一致性

1. 导致数据不一致的原因

当数据发生变化的时候,需要同时去更新Redis和Mysql,更新数据是有先后顺序的,在极端情况下就会出现数据一致性的问题。

1. 先更新数据库再更新缓存

如果先更新数据库,若是缓存中的数据更新失败,就会出现数据库和redis中的数据不一致问题

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

先删除缓存再更新数据库,在理想情况删除了缓存,更新了数据库,再第二次请求的时候会发现缓存是空的,会去读取数据库将数据缓存起来。

但是

删除缓存和更新数据库不是一个原子操作,若是缓存删除了,此时,第二条线程抢到CPU时间轮片,开始读取数据,发现没有缓存,查询数据库,并将数据缓存起来,此时第一条线程拿到CPU时间轮片,开始更新数据库,这个情况下会导致数据库和缓存不一致

采用最终一致性的方案解决

1. 采用延迟双删除的策略

具体步骤

  1. 先删除缓存
  2. 写入数据库
  3. 休眠500毫秒(视情况而定)
  4. 再次删除缓存

具体实现

public void write(String key,Object data){
     redis.delKey(key); // 删除缓存
     db.updateData(data); // 更新数据库
     Thread.sleep(500); // 睡眠延迟
     redis.delKey(key);// 再次删除缓存
 }

2. 异步更新缓存(基于订阅Binlog)

读取MysqlBinlog日志后分析,利用消息队列,推送更新到redis缓存中,这样一旦产生了新的写入,更新,删除等操作,就可以把相关的更新推送到redis中

其实这种机制类似于Mysql的主从备份,Mysql的主从备份也是通过Binlog来实现数据一致性
这里的消息推送工具可以使用Kafka、rabbitMQ等消息队列来实现

结合使用canal(阿里的一款开源框架),通过该框架可以对MySQL的binlog进行订阅

因为是最终一致性,所以业务如果无法接收短期不一致性的话就得更换策略

版权属于:都依凡 所有,采用《知识共享署名许可协议》进行许可,转载请注明文章来源。

本文链接: http://blog.anlucky.cn/index.php/programming/database/166

赞 (7)

评论区(暂无评论)

啊哦,评论功能已关闭~