Canal探究

canal主要用途是基于 MySQL 数据库增量日志解析 , 提供增量数据订阅和消费 。
应用场景:

  • 异构数据同步
  • 数据库实时备份
  • 业务cache刷新
原理canal模拟成mysql slave向master发送dump请求 , 收到binlog数据进行解析
Canal探究文章插图
slave同步master原理:
  • master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件 , binary log events , 可以通过show binlog events进行查看)
  • slave将binary log events拷贝到它的中继日志(relay log)
  • slave重做中继日志中的事件 , 将改变反映它自己的数据

Canal探究文章插图
架构
Canal探究文章插图
server代表一个canal运行实例 , 对应于一个jvm
instance对应一个数据队列 , 一个destination , 相当于一个数据库实例变更的监听 , 1个server对应1-n个instance
instance模块:
  • eventParser (数据源接入 , 模拟slave协议和master进行交互 , 协议解析)
  • eventSink (Parser和Store链接器 , 进行数据过滤 , 加工 , 分发的工作)
  • eventStore (数据存储)
  • metaManager (增量订阅 --tt-darkmode-bgcolor: #131313;">EventParser
    Canal探究文章插图
    1. Connection获取上一次解析成功的位置 (如果第一次启动 , 则获取初始指定的位置或者是当前数据库的binlog位点)
    2. Connection建立链接 , 发送BINLOG_DUMP指令
    3. Mysql开始推送Binaly Log
    4. 接收到的Binaly Log的通过Binlog parser进行协议解析 , 补充一些特定信息
    5. 传递给EventSink模块进行数据存储 , 是一个阻塞操作 , 直到存储成功
    6. 存储成功后 , 定时记录Binaly Log位置
    EventSink
    Canal探究文章插图
    • 数据过滤:支持通配符的过滤模式 , 表名 , 字段内容等
    • 数据路由/分发:解决1:n (1个parser对应多个store的模式)
    • 数据归并:解决n:1 (多个parser对应1个store)
    • 数据加工:在进入store之前进行额外的处理 , 比如join
    EventStore
    Canal探究文章插图
    Instance设计
    Canal探究文章插图
    instance代表了一个实际运行的数据队列 , 包括了EventPaser,EventSink,EventStore等组件 。 抽象了CanalInstanceGenerator , 主要是考虑配置的管理方式:
    • manager方式:提供http方式 , 可以和公司内部web console/manager系统进行对接 。
    • spring方式:基于spring xml + properties进行定义 , 通过spring配置
    Spring配置spring配置的原理是将整个配置抽象为两部分:
    • xxxx-instance.xml (canal组件的配置定义 , 可以在多个instance配置中共享 , 在canal.properties中配置)
    • xxxx.properties (每个instance通道都有各自一份定义 , 因为每个mysql的ip , 帐号 , 密码等信息不会相同)
    通过spring的PropertyPlaceholderConfigurer通过机制将其融合 , 生成一份instance实例对象 , 每个instance对应的组件都是相互独立的 , 互不影响
    properties配置文件properties配置分为两部分:
    • canal.properties (系统根配置文件 , 配置destinations , 注册IP , 启动端口)
    • instance.properties (instance级别的配置文件 , 每个instance一份 , 配置数据库信息 , 监听的表)
    canal.properties介绍:
    canal配置主要分为两部分定义:
    • instance列表定义 (列出当前server上有多少个instance , 每个instance的加载方式是spring/manager等)
    • common参数定义 , 比如可以将instance.properties的公用参数 , 抽取放置到这里 , 这样每个instance启动的时候就可以共享. 【instance.properties配置定义优先级高于canal.properties】
    canal如何维护一份增量订阅 --tt-darkmode-bgcolor: #131313;">解析位点 (parse模块会记录 , 上一次解析binlog到了什么位置 , 对应组件为:CanalLogPositionManager)
  • 消费位点 (canal server在接收了客户端的ack后 , 就会记录客户端提交的最后位点 , 对应的组件为:CanalMetaManager)
对应的两个位点组件 , 目前都有几种实现: