如何保证redis和mysql的数据一致性
参考:面试官:3 种缓存更新策略是怎样的? - 小林coding - 博客园
腾讯二面:Redis与MySQL一致性如何保证?_牛客网
旁路缓存模式(Cache Aside Pattern)
适合读多写少的场景,因为当写入比较频繁时,缓存会被频繁删除,对缓存的命中率有影响。
读时先读redis,读不到则查mysql,写时先更新mysql,然后删除redis缓存。
而上述成功的前提这两个操作都能同时执行成功,所以问题就是,在删除缓存(第二个操作)的时候失败了,导致缓存中的数据是旧值,而数据库是最新值。如何保证两个操作都能执行成功?
- 消息队列重试机制
消息队列来重试缓存的删除,优点是保证缓存一致性的问题,缺点会对业务代码入侵- 订阅MySQL binlog,再操作缓存
订阅MySQL binlog + 消息队列 + 重试缓存的删除,优点是规避了代码入侵问题,也很好的保证缓存一致性的问题,缺点就是引入的组件比较多。
做法:将 binlog 日志采集发送到 MQ 队列里面,然后编写一个简单的缓存删除消息者订阅 binlog 日志,根据更新 log 删除缓存,并且通过 ACK 机制确认处理这条更新 log,保证数据缓存一致性。
这两种方法有一个共同的特点,都是采用异步操作缓存。
异步更新(Write Behind)
实时性要求较高的场景中,可以先更新 Redis 缓存,然后再异步更新 MySQL 数据库。
双写操作(Write Through)
在某些业务场景中,需要同时更新 Redis 和 MySQL 的数据。
延迟回写(Write Back)
Redis 中数据更新后并不立即同步更新 MySQL,而是在特定时机触发数据批量回写。