初识增量数据同步组件-canal
canal 是阿里巴巴 MySQL 数据库 Binlog 的增量订阅&消费组件。
早期,阿里巴巴 B2B 公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求。不过早期的数据库同步业务,主要是基于 trigger 的方式获取增量 变更,不过从 2010 年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务,从此开 启了一段新纪元。ps. 目前内部使用的同步,已经支持 MySQL 5.x 和 Oracle 部分版本的日志解析
实现原理
-
mysql 原生主备复制实现
从上层来看,复制分成三步:- master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events,可以通过show binlog events进行查看);
- slave将master的binary log events拷贝到它的中继日志(relay log);
- slave重做中继日志中的事件,将改变反映它自己的数据。
-
canal的工作原理
原理相对比较简单:- canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
- mysql master收到dump请求,开始推送binary log给slave(也就是canal)
- canal解析binary log对象(原始为byte流)
架构设计
说明:
- server代表一个canal运行实例,对应于一个jvm
- instance对应于一个数据队列 (1个server对应1…n个instance)
- instance模块:
- eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
- eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
- eventStore (数据存储)
- metaManager (增量订阅&消费信息管理器)
- 目前canal只能支持row模式的增量订阅(statement只有sql,没有数据,所以无法获取原始的变更日志)
系统部署
部署分为两大块,服务端和客户端;服务端负责数据采集、发送,客户端负责数据接收,数据处理
-
部署要求
安装部署客户端和服务端两台服务器网络必须相互打通,两台机器存在相同的mysql,且版本尽量保存一致,如果有必要,可以先做好数据同步,可根据实际情况来 -
服务端部署
- 确认如下端口是否可用,如果不可用修改conf/canal.properties
canal.port = 11111
canal.metrics.pull.port = 11112
canal.mq.servers = 127.0.0.1:6667
Windows 系统启动需要确定9099端口是否可用,如果不可用修改bin/startup.bat文件9099端口配置 - 修改需要同步的服务端的数据库信息,配置文件在conf/example/instance.properties
canal.instance.master.address=127.0.0.1:3306
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.defaultDatabaseName=nsac - 确认并修改以上信息后,就可以启动了,执行bin/startup.sh
- 确认如下端口是否可用,如果不可用修改conf/canal.properties
-
客户端部署
- 1.部署客户端需要搞明白两点,服务端是“谁”,数据给“谁”,找到BOOT-INF\classes\目录下的application.properties配置文件
确定如上配置后启动客户端,执行start.sh即可
- 1.部署客户端需要搞明白两点,服务端是“谁”,数据给“谁”,找到BOOT-INF\classes\目录下的application.properties配置文件
HA机制设计
canal的ha分为两部分,canal server和canal client分别有对应的ha实现
canal server: 为了减少对mysql dump的请求,不同server上的instance要求同一时间只能有一个处于running,其他的处于standby状态.
canal client: 为了保证有序性,一份instance同一时间只能由一个canal client进行get/ack/rollback操作,否则客户端接收无法保证有序。
整个HA机制的控制主要是依赖了zookeeper的几个特性,watcher和EPHEMERAL节点(和session生命周期绑定),可以看下我之前zookeeper的相关文章。
Canal Server:
大致步骤:
canal server要启动某个canal instance时都先向zookeeper进行一次尝试启动判断 (实现:创建EPHEMERAL节点,谁创建成功就允许谁启动)
创建zookeeper节点成功后,对应的canal server就启动对应的canal instance,没有创建成功的canal instance就会处于standby状态
一旦zookeeper发现canal server A创建的节点消失后,立即通知其他的canal server再次进行步骤1的操作,重新选出一个canal server启动instance.
canal client每次进行connect时,会首先向zookeeper询问当前是谁启动了canal instance,然后和其建立链接,一旦链接不可用,会重新尝试connect.
Canal Client的方式和canal server方式类似,也是利用zokeeper的抢占EPHEMERAL节点的方式进行控制
以上就是canal组件的初步认识了,其实canal可以用到很多的场合:
- 数据库镜像
- 数据库实时备份
- 多级索引 (卖家和买家各自分库索引)
- search build
- 业务cache刷新
- 价格变化等重要业务消息
我这边用的比较多的业务就是数据库备份、数据库同步、业务cache缓存刷新、redis数据同步等
我把demo源码发布出来,可以下载参考一下
客户端源码:https://download.****.net/download/weixin_37727274/12584739
服务端程序:https://download.****.net/download/weixin_37727274/12584743