基于MySql BinLog的增量订阅和消费组件 Canal

1、Canal背景

早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求。不过早期的数据库同步业务,主要是基于trigger的方式获取增量变更,不过从2010年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务,从此开启了一段新纪元。

2、Canal原理

2.1mysql主备复制实现

从上层来看,复制分成三步:

master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events,可以通过show binlog events进行查看);

slave将master的binary log events拷贝到它的中继日志(relay log);

slave重做中继日志中的事件,将改变反映它自己的数据。

2.2canal的工作原理:

canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议

mysql master收到dump请求,开始推送binary log给slave(也就是canal)

canal解析binary log对象(原始为byte流)

3、Canal的配置文件

canal配置方式有两种:

  1. ManagerCanalInstanceGenerator: 基于manager管理的配置方式,目前alibaba内部配置使用这种方式
  2. SpringCanalInstanceGenerator:基于本地spring xml的配置方式,目前开源版本已经自带该功能所有代码,大部采用此种方式

3.1Spring配置

spring配置的原理是将整个配置抽象为两部分:

  1. xxxx-instance.xml:

conf/spring目录下的配置文件,如(memory/file/default/group)-instance.xml,canal组件的配置定义。

  1. xxxx.properties:

包含系统根配置文件canal.properties和instance.properties(定义不同的数据库实例)每个instance通道都有各自一份定义,因为每个mysql的ip,帐号,密码等信息不会相同

3.1.1xxxx-instance.xml

在介绍instance配置之前,先了解一下canal如何维护一份增量订阅&消费的关系信息:

  1. 解析位点 (parse模块会记录,上一次解析binlog到了什么位置,对应组件为:CanalLogPositionManager)
  2. 消费位点 (canal server在接收了客户端的ack后,就会记录客户端提交的最后位点,对应的组件为:CanalMetaManager)

那么,在canal中是如何配置实现的呢?通过在canal的根配置文件中(canal.properties),指定当前canal启动时,采用那种方式来定义组件,默认是文件方式:

 

定义的组件包括:

eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)、eventSink (Parser和Store链接器,进行过滤(表、字段),路由分发,归并,加工的工作)、eventStore (数据存储--记录存储、消费、订阅的位置信息)、metaManager (增量订阅&消费信息管理器)

3.1.1.1memory-instance.xml

所有的组件(parser , sink , store)都选择了内存版模式,记录位点的都选择了memory模式,重启后又会回到初始位点进行解析 。
特点:速度最快,依赖最少(不需要zookeeper)
场景:一般应用在quickstart,或者是出现问题后,进行数据分析的场景,不应该将其应用于生产环境

3.1.1.2default-instance.xml

store选择了内存模式,其余的parser/sink依赖的位点管理选择了持久化模式,目前持久化的方式主要是写入zookeeper,保证数据集群共享. 
特点:支持canalServer HA
场景:生产环境,集群化部署----我们采用此方式

3.1.1.3group-instance.xml

主要针对需要进行多库合并时,可以将多个物理instance(数据库实例)合并为一个逻辑instance,提供客户端访问。
    场景:分库业务。 比如产品数据拆分了4个库,每个库会有一个instance(canal解压后的conf目录下包含instance.properties的文件夹),如果不用group,业务上要消费数据时,需要启动4个客户端(在客户端指定destination),分别链接4个instance实例。使用group后,可以在canal server上合并为一个逻辑instance,只需要启动1个客户端,链接这个逻辑instance即可

3.1.2xxxx-properties

xxxx-properties配置分为两部分:

canal.properties---- 系统根配置文件-canalServer的启动配置

instance.properties----instance级别的配置文件,每个instance(数据库)一份

注意:instance.properties配置定义优先级高于canal.properties

3.1.2.1canal.properties

参数名字

参数说明

默认值

canal.destinations

当前server上部署的instance列表

canal.conf.dir

conf/目录所在的路径

../conf

canal.auto.scan

开启instance自动扫描
如果配置为true,canal.conf.dir目录下的instance配置变化会自动触发:
a. instance目录新增: 触发instance配置载入,lazy为true时则自动启动
b. instance目录删除:卸载对应instance配置,如已启动则进行关闭
c. instance.properties文件变化:reload instance配置,如已启动自动进行重启操作

true

canal.auto.scan.interval

instance自动扫描的间隔时间,单位秒

5

canal.instance.global.mode

全局配置加载方式

spring

canal.instance.global.lazy

全局lazy模式

false

canal.instance.global.manager.address

全局的manager配置方式的链接信息

canal.instance.global.spring.xml

全局的spring配置方式的组件文件

classpath:spring/memory-instance.xml 
 (spring目录相对于canal.conf.dir)

canal.instance.example.mode
canal.instance.example.lazy
canal.instance.example.spring.xml
.....

instance级别的配置定义,如有配置,会自动覆盖全局配置定义模式
命名规则:canal.instance.{name}.xxx

canal.instance.tsdb.spring.xml

v1.0.25版本新增,全局的tsdb配置方式的组件文件

classpath:spring/tsdb/h2-tsdb.xml (spring目录相对于canal.conf.dir)

通用参数定义

参数名字

参数说明

默认值

canal.id

每个canal server实例的唯一标识,暂无实际意义

1

canal.ip

canal server绑定的本地IP信息,如果不配置,默认选择一个本机IP进行启动服务

canal.port

canal server提供socket服务的端口

11111

canal.zkServers

canal server链接zookeeper集群的链接信息
例子:10.20.144.22:2181,10.20.144.51:2181

canal.zookeeper.flush.period

canal持久化数据到zookeeper上的更新频率,单位毫秒

1000

canal.instance.memory.batch.mode

canal内存store中数据缓存模式
1. ITEMSIZE : 根据buffer.size进行限制,只限制记录的数量
2. MEMSIZE : 根据buffer.size  * buffer.memunit的大小,限制缓存记录的大小

MEMSIZE

canal.instance.memory.buffer.size

canal内存store中可缓存buffer记录数,需要为2的指数

16384

canal.instance.memory.buffer.memunit

内存记录的单位大小,默认1KB,和buffer.size组合决定最终的内存使用大小

1024

canal.instance.transactionn.size

最大事务完整解析的长度支持
超过该长度后,一个事务可能会被拆分成多次提交到canal store中,无法保证事务的完整可见性

1024

canal.instance.fallbackIntervalInSeconds

canal发生mysql切换时,在新的mysql库上查找binlog时需要往前查找的时间,单位秒
说明:mysql主备库可能存在解析延迟或者时钟不统一,需要回退一段时间,保证数据不丢

60

canal.instance.detecting.enable

是否开启心跳检查

false

canal.instance.detecting.sql

心跳检查sql

insert into retl.xdual values(1,now()) on

duplicate key update x=now()

canal.instance.detecting.interval.time

心跳检查频率,单位秒

3

canal.instance.detecting.retry.threshold

心跳检查失败重试次数

3

canal.instance.detecting.heartbeatHaEnable

心跳检查失败后,是否开启自动mysql自动切换
说明:比如心跳检查失败超过阀值后,如果该配置为true,canal就会自动链到mysql备库获取binlog数据

false

canal.instance.network.receiveBufferSize

网络链接参数,SocketOptions.SO_RCVBUF

16384

canal.instance.network.sendBufferSize

网络链接参数,SocketOptions.SO_SNDBUF

16384

canal.instance.network.soTimeout

网络链接参数,SocketOptions.SO_TIMEOUT

30

canal.instance.filter.druid.ddl

是否使用druid处理所有的ddl解析来获取库和表名

true

canal.instance.filter.query.dcl

是否忽略dcl语句

false

canal.instance.filter.query.dml

是否忽略dml语句
(mysql5.6之后,在row模式下每条DML语句也会记录SQL到binlog中,可参考MySQL文档)

false

canal.instance.filter.query.ddl

是否忽略ddl语句

false

canal.instance.filter.table.error

是否忽略binlog表结构获取失败的异常

(主要解决回溯binlog时,对应表已被删除或者表结构和binlog不一致的情况)

false

canal.instance.filter.rows

是否dml的数据变更事件

(主要针对用户只订阅ddl/dcl的操作)

false

canal.instance.filter.transaction.entry

是否忽略事务头和尾,比如针对写入kakfa的消息时,不需要写入TransactionBegin/Transactionend事件

false

canal.instance.binlog.format

支持的binlog format格式列表
(otter会有支持format格式限制)

ROW,STATEMENT,MIXED

canal.instance.binlog.image

支持的binlog image格式列表
(otter会有支持format格式限制)

FULL,MINIMAL,NOBLOB

canal.instance.get.ddl.isolation

ddl语句是否单独一个batch返回

(比如下游dml/ddl如果做batch内无序并发处理,会导致结构不一致)

false

canal.instance.parser.parallel

是否开启binlog并行解析模式

(串行解析资源占用少,但性能有瓶颈, 并行解析可以提升近2.5倍+)

true

canal.instance.parser.parallelBufferSize

binlog并行解析的异步ringbuffer队列
(必须为2的指数)

256

canal.instance.tsdb.enable

是否开启tablemeta的tsdb能力

true

canal.instance.tsdb.dir

主要针对h2-tsdb.xml时对应h2文件的存放目录,默认为conf/xx/h2.mv.db

${canal.file.data.dir:../conf}/${canal.instance.destination:}

canal.instance.tsdb.url

jdbc url的配置

(h2的地址为默认值,如果是mysql需要自行定义)

jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_S

IZE=1000;MODE=MYSQL;

canal.instance.tsdb.dbUsername

jdbc url的配置

(h2的地址为默认值,如果是mysql需要自行定义)

canal

canal.instance.tsdb.dbPassword

jdbc url的配置

(h2的地址为默认值,如果是mysql需要自行定义)

canal

canal.instance.rds.accesskey

aliyun账号的ak信息 (如果不需要在本地binlog超过18小时被清理后自动下载oss上的binlog,可以忽略该值)

canal.instance.rds.secretkey

aliyun账号的sk信息

(如果不需要在本地binlog超过18小时被清理后自动下载oss上的binlog,可以忽略该值)

3.1.2.2instance.properties

在canal.properties定义了canal.destinations后,需要在canal.conf.dir对应的目录下建立同名的文件,比如:canal.destinations = example1,example2,这时需要创建example1和example2两个目录,每个目录里各自有一份instance.properties。canal自带了一份instance.properties,可直接复制conf/example目录进行配置修改

cp -R example example1/

cp -R example example2/

如果canal.properties未定义instance列表,但开启了canal.auto.scan时,server第一次启动时,会自动扫描conf目录下,将文件名做为instance name,启动对应的instance,canalServer运行过程中,会根据canal.auto.scan.interval定义的频率,进行扫描
1. 发现目录有新增,启动新的instance
2. 发现目录有删除,关闭老的instance
3. 发现对应目录的instance.properties有变化,重启instance

instance.properties参数列表

参数名字

参数说明

默认值

canal.instance.mysql.slaveId

mysql集群配置中的serverId概念,需要保证和当前mysql集群中id唯一
(v1.1.x版本之后canal会自动生成,不需要手工指定)

canal.instance.master.address

mysql主库链接地址

127.0.0.1:3306

canal.instance.master.journal.name

mysql主库链接时起始的binlog文件

canal.instance.master.position

mysql主库链接时起始的binlog偏移量

canal.instance.master.timestamp

mysql主库链接时起始的binlog的时间戳

canal.instance.gtidon

是否启用mysql gtid的订阅模式

false

canal.instance.master.gtid

mysql主库链接时对应的gtid位点

canal.instance.dbUsername

mysql数据库帐号

canal

canal.instance.dbPassword

mysql数据库密码

canal

canal.instance.defaultDatabaseName

mysql链接时默认schema

canal.instance.connectionCharset

mysql 数据解析编码

UTF-8

canal.instance.filter.regex

mysql 数据解析关注的表,Perl正则表达式.

多个正则之间以逗号(,)分隔,转义符需要双斜杠(\\)


常见例子:

1.  所有表:.*   or  .*\\..*
2.  canal schema下所有表: canal\\..*
3.  canal下的以canal打头的表:canal\\.canal.*
4.  canal schema下的一张表:canal.test1

5.  多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)

.*\\..*

canal.instance.filter.black.regex

mysql 数据解析表的黑名单,表达式规则见白名单的规则

canal.instance.rds.instanceId

aliyun rds对应的实例id信息

(如果不需要在本地binlog超过18小时被清理后自动下载oss上的binlog,可以忽略该值)

4、HA模式配置

4.1HA原理

在Canal的设计中,基于对容灾的考虑,往往会配置两个或更多个CanalServer来负责一个MySQL数据库实例的数据增量复制。canal的ha分为两部分,canal server和canal client分别有对应的ha实现,整个HA机制的控制主要是依赖了zookeeper的几个特性,watcher和EPHEMERAL节点(和session生命周期绑定)

1、canal server: 为了减少对mysql dump的请求,不同server上的instance要求同一时间只能有一个处于running,其他的处于standby状态.

2、canal client: 为了保证有序性,一份instance同一时间只能由一个canal client进行get/ack/rollback操作,否则客户端接收无法保证有序。

 

大致步骤:

1、canal server要启动某个canal instance时都先向zookeeper进行一次尝试启动判断 (实现:创建EPHEMERAL节点,谁创建成功就允许谁启动)

2、创建zookeeper节点成功后,对应的canal server就启动对应的canal instance,没有创建成功的canal instance就会处于standby状态

3、一旦zookeeper发现canal server A创建的节点消失后,立即通知其他的canal server再次进行步骤1的操作,重新选出一个canal server启动instance.

4、canal client每次进行connect时,会首先向zookeeper询问当前是谁启动了canal instance,然后和其建立链接,一旦链接不可用,会重新尝试connect.

Canal Client的HA方式和canal server方式类似,也是利用zookeeper的抢占EPHEMERAL节点的方式进行控制.

4.2实施配置

参考https://blog.csdn.net/feiying0canglang/article/details/105612204

4.2.1下载canal

 

4.2.2上传到服务器

1、解压配置canal.properties

 

 

创建mvsbase文件夹

修改instance.properties

 

 

 

 

修改下图配置,否则当表结构发生变化时,由于binlog数据包含以前表结构的数据,此时cannal解析时就会 parse row data fail

 

 

启动canal: sh startup.sh

 

4.2.3canalServer高可用

拷贝4.2.2的canal在另一台机器上部署canalserver,配置一模一样。

启动后查看zookeeper:

ls /otter/canal/cluster:

停掉46再次查看ls /otter/canal/cluster:

启动46查看ls /otter/canal/destinations/mvsbase/cluster

查看mvsbase(代表监控的mysql)

 

停止56查看ls /otter/canal/destinations/mvsbase/cluster

查看get /otter/canal/destinations/mvsbase/running

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值