Canal从Mysql获取binlog日志的通信过程详解

简介

本文主要以Mysql为例,分析canal的parser模块是如何从mysql拉取数据的。

核心

canal的官网中介绍到,canal的工作原理简单分为如下几步:

  1. canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
  2. mysql master收到dump请求,开始推送binary log给slave(也就是canal)
  3. canal解析binary log对象(原始为byte流)

在canal的parser模块中,有一个抽象类AbstractEventParser,该类中定义了一个线程,该线程每10秒向Mysql的Master节点发送一次dump请求,用于请求binlog日志数据,然后把binlog数据存储到一个大小为1024的ringbuffer缓存队列中,整个流程如下图所示:

下面将详细介绍一个完整的canal请求binlog日志的过程:

  1. 首先会启动一个心跳线程,该心跳线程只作用于parser模块和sink模块,每秒向sink模块推送一个心跳报文。

  2. 在创建与Mysql节点的连接之前,需要做一些准备工作,比如确定binlog的FORMAT以及binlog_row_image参数的值

  3. 建立与Mysql的连接,在instance.properties文件中会配置Master的地址端口以及对应的数据库用户名密码,此处就是利用这些信息建立与Master的连接。

  4. 获取到Mysql的ServerId

  5. 获取最后的位置信息,也就是上一次与Master通信后读取到的binlog的位置,该位置信息也会写入meta.dat文件中,因此如果内存中没有,会尝试从该文件中读取。

  6. 重新链接,因为在找position过程中可能有状态变更,需要断开后重建。

  7. 调用dump()方法开始获取pbinglog数据,同时注册一个回调事件用于接收返回的binlog数据。

  8. sleep10秒,重新执行上述流程。

当有回调事件返回时,处理流程如下

  1. 调用BinlogParser类的parse()方法将返回的二进制binlog数据LogEvent,解析成canal封装好的Entry事件,LogEvent中包含一个事件类型eventType,详细区分了该事件是查询操作还是写操作,或者是心跳等各种类型。
  2. 调用EventTransactionBuffer类的add()方法将Entry事件添加到一个大小为1024的ringbuffer中。
  3. EventTransactionBuffer会在一定的条件下把ringbuffer中的Entry事件推送到sink模块。

至此,parser模块下的canal与mysql的通信过程全部结束。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章