阿里canal的理解

您所在的位置:网站首页 carbox盒子 阿里canal的理解

阿里canal的理解

#阿里canal的理解| 来源: 网络整理| 查看: 265

一:什么是canal

阿里巴巴B2B公司,因为业务的特性,卖家主要集中在国内,买家主要集中在国外,所以衍生出了杭州和美国异地机房的需求,从2010年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务。

canal是用java开发的基于数据库增量日志解析,提供增量数据订阅&消费的中间件。目前,canal主要支持了MySQL的binlog解析,解析完成后才利用canal client 用来处理获得的相关数据。(数据库同步需要阿里的otter中间件,基于canal)

二:canal的工作机制

1.mysql主从复制的工作机制:

复制过程分成三步:

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

(2) Slave从库向mysql master发送dump协议,将master主库的binary log events拷贝到它的中继日志(relay log);

(3) Slave从库读取并重做中继日志中的事件,将改变的数据同步到自己的数据库。

 

Binary Log:包含了一些数据库的事件,这些事件描述了数据库的改动,如建表、数据改动等。

 

2. canal的工作机制:

原理如下:

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

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

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

 

3. MySQL本身的binlog主从同步的限制:

 

首先,架构单一,不灵活:MySQL本身支持双主同步,不会发生回环的原因是执行relay log中的sql不会再被写回binlog。

第二,主从同步受限于同构表级别的同步。而且,不能控制是否同步DDL。

第三,MySQL的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,问题来了,slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随即的,不是顺序的,成本高很多。

第四,MySQL的主从同步传输的binlog包是完整的binlog,未经压缩,有时候网络压力会很大。

 

4. 为什么使用canal?

(1). 更灵活的架构,多机房同步比较简单。

(2). 异构表之间也可以同步,同时,可以控制不同步DDL以免出现数据丢失和不一致。

(3). Canal可以实现一个表一线程,多个表多线程的同步,速度更快。同时会压缩简化要传输的binlog,减少网络压力。

(4). 双A机房同步. 目前mysql的M-M部署结构,不支持解决数据的一致性问题,基于canal的双向复制+一致性算法,可一定程度上解决这个问题,实现双A机房.

 

5. canal处理binlog的流程

三.Canal内部组件解析

 

1)instance内部有EventParser、EventSink、EventStore、metaManager主要四个组件构成,当然还有其他的守护组件比如monitor、HA心跳检测、ZK事件监听等。对象实例初始化和依赖关系,可以参见“default-instance.xml”,其配置模式为普通的Spring。(源码:SpringCanalInstanceGenerator)。

2)Parser主要用于解析指定"数据库"的binlog,内部基于JAVA实现了“binlog dump”、“show master status”等。Parser会与ZK交互,并获取当前instance所有消费者的cursor,并获其最小值,作为此instance解析binlog的起始position。目前的实现方式是,一个instance同时只能有一个consumer处于active消费状态,ClientId为定值“1001”,“cursor”中包含consumer消费binlog的position,数字类型。由此可见,Canal instance本身并没有保存binlog的position,Parser中继操作是根据consumer的消费cursor位置来决定;对于信息缺失时,比如Canal集群初次online,且在“default-instance.xml”中也没有指定“masterPositiion”信息(每个instance.properties是可以指定起始position的),那么将根据“show master status”指令获取当前binlog的最后位置。

(源码:MysqlEventParser.findStartPosition())

 

3)Parser每次、批量获取一定条数的binlog,将binlog数据封装成event,并经由EventSink将消息转发给EventStore,Sink的作用就是“协调Parser和Store”,确保binglog的解析速率与Store队列容量相容。

(源码:AbstractEventParser.start(),EntryEventSink.sink())

 

4)EventStore,用于暂存“尚未消费”的events的存储队列,默认基于内存的阻塞队列实现。Store中的数据由Sink组件提交入队,有NettyServer服务的消费者消费确认后出队,队列的容量和容量模式由“canal.properties”中的“memory”相关配置决定。当Store中容量溢满时,将会阻塞Sink操作(间接阻塞Parser),所以消费者的效能会直接影响instance的同步效率。

 

5)metaManager:主要用于保存Parser组件、CanalServer(即本文中提到的NettyServer)、Canal Instances的meta数据,其中Parser组件涉及到的是binlog position、CanalServer与消费者交互时ACK的Cursor信息、instance的集群运行时信息等。根据官方解释,我们在生产环境级别、高可靠业务要求场景下,metaManager建议基于Zookeeper实现。

 

其中有关Position信息由CanalLogPositionManager类负责,其实现类有多个,在Cluster模式下,建议基于FailbackLogPositionManager,其内部有“primary”、“failback”两级组合,优先基于primary来存取Position,只有当primary异常时会“降级”使用failback;其配置模式,建议与“default-instance.xml”保持一致。

四.Canal配置文件分析

canal.properties 是全局配置文件,instance.properties中如果有没有配置的项,就会从canal.propertie中取,如果没有就会取默认值。

​​​​################################################# ## mysql serverId canal.instance.mysql.slaveId = 1234 #position info, #改成自己的数据库地址 canal.instance.master.address = 127.0.0.1:3306 canal.instance.master.journal.name = canal.instance.master.position = canal.instance.master.timestamp = #备用数据库 #canal.instance.standby.address = #canal.instance.standby.journal.name = #canal.instance.standby.position = #canal.instance.standby.timestamp = #username/password,改成自己的数据库的用户名和密码 canal.instance.dbUsername = canal.instance.dbPassword = canal.instance.defaultDatabaseName = canal.instance.connectionCharset = UTF-8 #table regex canal.instance.filter.regex = .\.. #################################################

其它内容,网上有很多,这里就只写下自己的理解吧。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3