redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

在项目中,我们主要通过 Redisson 的读写锁机制 来保证数据的强一致性

当执行读取操作时,我们会加上读锁(共享锁),这样可以做到:

  • 读读不互斥;
  • 读写互斥。

而在更新数据时,我们会加上写锁(排他锁),此时写写、读写都互斥。
这样可以确保在写入数据库的同时,其他线程无法读取缓存数据,从而避免出现脏读不一致的情况。
这里需要注意的一点是:读写方法必须使用同一把锁,才能真正保证互斥关系成立。


除了使用分布式锁,我们也考虑过使用 “延迟双删”策略 来实现最终一致性

具体做法是:

  1. 先删除缓存;
  2. 再更新数据库;
  3. 最后延时一段时间后,再删除一次缓存。

不过,延迟的时间点很难精确把握。在延时窗口内仍可能出现脏数据问题,无法满足强一致性场景,因此我们最终没有采用这种方式。


在我最近做的项目中(例如简历中提到的 xxxx 功能),
系统对数据一致性的实时性要求没有那么高,可以接受一定的同步延时。

因此我们采用了 阿里巴巴的 Canal 组件 来实现最终一致性的数据同步

Canal 的原理是:

  • 将自己伪装成 MySQL 的从节点;
  • 通过监听 binlog(数据库增删改日志) 来捕获数据变更;
  • Canal 服务解析 binlog 后,将变更数据推送给客户端;
  • 客户端根据变更内容更新或删除 Redis 缓存。

这种方式的优点是:

  • 不需要修改业务代码
  • 同步过程自动化;
  • 能在大多数业务场景下保证“最终一致性”。