Redis和MySQL这对黄金组合在很多场景中都会被应用到。但如何保证Redis缓存中的数据同步一直都是开发过程中比较关注的问题。那么今天将介绍其中一种解决方案,后续如果还有更好的解决方案将持续更新。
先存储到Redis,再同步到MySQL
- 客户端有数据来了之后,先将其保存到Redis中,然后再同步到MySQL中。
2)这种方案本身也是不安全/不可靠的,因此如果Redis存在短暂的宕机或失效,那么会丢失数据。
先写入MySQL,再通知Redis读取MySQL并同步
- 客户端先将数据写入MySQL, 再以某种方式通知Redis去数据库读取数据并更新缓存
- 这种方案对于写比较频繁的操作,通知会比较频繁从而会增加MySQL的读取压力。只适用写比较少的场景。
Canal 解析 MySQL 的binlog,将数据库中的数据同步到Redis
在MySQL的主从架构中,
1) 主服务器操作数据,并将数据写入Bin log。
2) 从服务器从主服务器读取Bin log并写入自己的Relay log中,然后解析Relay log中的数据,从而将数据同步到自己的数据库。
基于上述过程,我们的脑海中是否闪现过这样一道火花;我Redis也可以模仿人家从服务器,读取Bin log将数据同步到自己的数据库呀。的确,只要Redis能遵循MySQL主从复制的协议规范,来实现数据同步,未来还是可期的。
在实践中一款叫Canal的框架确实帮我们解决了这个问题。
canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB。
工作原理(模仿MySQL复制):
- canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
- mysql master收到dump请求,开始推送binary log给slave(也就是canal)
- canal解析binary log对象(原始为byte流)
加粗样式架构:
. server代表一个canal运行实例.
. instance对应于一个数据队列 (1个server对应1…n个instance)
instance模块:
. eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
. eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
. eventStore (数据存储)
. metaManager (增量订阅&消费信息管理器)
解析过程如下:
1) Parser解析MySQL的Bin log,然后将数据放入到sink中
2) sink对数据 进行过滤,加工,分发
3) store从sink中读取解析好的数据存储起来.
4)== 用自己设计的代码将store中的数据同步写入Redis中就可以. ==
5) 其中parse和sink是框架封装好的,我们做的是store的数据同步那一步。