通过数据源的事务日志抓取数据源变更,这能解决一致性问题(只要下游能保证变更应用到新库上)。它的问题在于各种数据源的变更抓取没有统一的协议,如,MySQL用binlog,MongoDB用oplog。
纯java开发,蛀牙用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费,目前canal只能支持row模式的增量订阅(statement只有sql,没有数据,所以无法获取原始的变更日志)
1、canal模拟MySQL salve的交互协议,伪装自己为MySQL salve,向MySQL master发送dump协议
2、MySQL master收到dump请求,开始推送binary log给salve(即canal)
3、canal解析binary log对象(原始为byte流)
从上图可知,复制可分为三步:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
通过deployer模块,启动一个canal-server,一个canal-server内部包含多个instance,每个instance都会伪装成一个Mysql实例的salve.client与server之间的通信协议有protocol模块定义。client订阅binlog信息时,需要传递一个destination参数,server会根据这个destination确定由那一个instance尾气提供服务。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
说明:
server代表一个canal运行实例,对应一个jvm
instance对应一个数据队列(1个server对应1…n个instance)
instance模块:
canal假装成MySQL Salve步骤:
一个binlog包含一个四字节的模数和一系列描述数据变更的Event,没一个Event又包含header和data两部分,大致结构如下:
基于Row的binlog主要包括以下几个Event:
TABLE_MAP_EVENT:描述变更的数据库表
WRITE_ROWS_EVENT:描述插入数据变更
UPDATE_ROWS_EVENT:描述修改数据变更
DELETE_ROWS_EVENT:描述删除数据变更
{"data":[{"BRAND_ID":"39103535-2d93-425b-a85e-c9709abf4c15","BRAND_NAME":"体验配方","BRAND_CODE":"5464365","BRAND_FLAG":"0","STATE":"0","CREATE_DATE":"2021-12-03","REMARK":"!","TS":"2021-12-03 12:04:13","CORP_ID":"50c43444-004c-44b9-a2d3-25c91a8b04c3"}],"database":"visdb_20210729","es":1638504356000,"id":43,"isDdl":false,"mysqlType":{"BRAND_ID":"varchar(36)","BRAND_NAME":"varchar(36)","BRAND_CODE":"varchar(36)","BRAND_FLAG":"int(2)","STATE":"int(2)","CREATE_DATE":"char(10)","REMARK":"varchar(200)","TS":"char(19)","CORP_ID":"varchar(36)"},"old":null,"pkNames":["BRAND_ID"],"sql":"","sqlType":{"BRAND_ID":12,"BRAND_NAME":12,"BRAND_CODE":12,"BRAND_FLAG":4,"STATE":4,"CREATE_DATE":1,"REMARK":12,"TS":1,"CORP_ID":12},"table":"bdp_brand","ts":1638504272407,"type":"INSERT"}
{"data":[{"BRAND_ID":"39103535-2d93-425b-a85e-c9709abf4c15","BRAND_NAME":"体验配方","BRAND_CODE":"5464365","BRAND_FLAG":"0","STATE":"0","CREATE_DATE":"2021-12-03","REMARK":"!!","TS":"2021-12-03 12:06:25","CORP_ID":"50c43444-004c-44b9-a2d3-25c91a8b04c3"}],"database":"visdb_20210729","es":1638504488000,"id":44,"isDdl":false,"mysqlType":{"BRAND_ID":"varchar(36)","BRAND_NAME":"varchar(36)","BRAND_CODE":"varchar(36)","BRAND_FLAG":"int(2)","STATE":"int(2)","CREATE_DATE":"char(10)","REMARK":"varchar(200)","TS":"char(19)","CORP_ID":"varchar(36)"},"old":[{"REMARK":"!","TS":"2021-12-03 12:04:13"}],"pkNames":["BRAND_ID"],"sql":"","sqlType":{"BRAND_ID":12,"BRAND_NAME":12,"BRAND_CODE":12,"BRAND_FLAG":4,"STATE":4,"CREATE_DATE":1,"REMARK":12,"TS":1,"CORP_ID":12},"table":"bdp_brand","ts":1638504404514,"type":"UPDATE"}
{
"data":null,"database":"visdb20210119","es":1638518233000,"id":15,"isDdl":true,"mysqlType":null,"old":null,"pkNames":null