redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)
redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)
在项目中,我们主要通过 Redisson 的读写锁机制 来保证数据的强一致性。
当执行读取操作时,我们会加上读锁(共享锁),这样可以做到:
- 读读不互斥;
- 读写互斥。
而在更新数据时,我们会加上写锁(排他锁),此时写写、读写都互斥。
这样可以确保在写入数据库的同时,其他线程无法读取缓存数据,从而避免出现脏读或不一致的情况。
这里需要注意的一点是:读写方法必须使用同一把锁,才能真正保证互斥关系成立。
除了使用分布式锁,我们也考虑过使用 “延迟双删”策略 来实现最终一致性。
具体做法是:
- 先删除缓存;
- 再更新数据库;
- 最后延时一段时间后,再删除一次缓存。
不过,延迟的时间点很难精确把握。在延时窗口内仍可能出现脏数据问题,无法满足强一致性场景,因此我们最终没有采用这种方式。
在我最近做的项目中(例如简历中提到的 xxxx 功能),
系统对数据一致性的实时性要求没有那么高,可以接受一定的同步延时。
因此我们采用了 阿里巴巴的 Canal 组件 来实现最终一致性的数据同步。
Canal 的原理是:
- 将自己伪装成 MySQL 的从节点;
- 通过监听 binlog(数据库增删改日志) 来捕获数据变更;
- Canal 服务解析 binlog 后,将变更数据推送给客户端;
- 客户端根据变更内容更新或删除 Redis 缓存。
这种方式的优点是:
- 不需要修改业务代码;
- 同步过程自动化;
- 能在大多数业务场景下保证“最终一致性”。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 彬子的Blog!



