基于Redis和MySQL的架构,如何保证数据一致性
-
一般情况下,Redis是用作应用程序和数据库之间读操作的缓存,主要目的是减少数据库IO,提升数据查询性能。
-
一般流程:
-
- 命中缓存,从缓存中加载数据
-
- 没有命中缓存,从数据库中加载数据
-
- 加载到的数据写入缓存
- 存在的问题:
当数据发生变化时,需要同时更新Redis和MySQL,可能出现一方更新失败,一方更新成功的情况,从而出现数据一致性问题。
- 解决办法:
-
- 先更新数据库,再更新缓存。如果缓存更新失败,就会导致数据库和Redis中的数据不一致。
-
- 先删除缓存,再更新数据库。这样下次访问Redis的时候,发现Redis中的数据是空的,这时候再加载。
- 但是在极端情况下,我们并不能保证删除Redis和更新数据库这两个操作的原子性。在这个过程中,如果有其他线程访问的话,还是会有数据一致性问题。所以在极端情况下,需要采用最终一致性方案
最终一致性方案:
-
MySQL更新数据库的数据
-
更新Redis中的数据
-
失败的请求写入MQ事务消息
-
异步重试,确保成功
还可以通过Canal组件监控binlog文件,从binlog中加载数据,然后同步到Redis中。