首页/数据/数据工程与 ETL 速查/Canal:伪装从库的增量订阅
CDC 与同步53 条

Canal:伪装从库的增量订阅

Canal 是阿里开源的 MySQL binlog 增量订阅组件(Java 实现):把自己伪装成从库,向主库发送 dump 协议请求,收到 binlog 后解析成结构化 Entry(含 RowChange),再投递给客户端或消息队列。在 Debezium/Flink CDC 普及前,它是国内使用较多的 CDC 方案。

Canal 是什么

Canal 是阿里开源的 MySQL 增量订阅组件(Java 实现):它把自己伪装成 MySQL 从库,向主库发送 dump 协议请求,接收主库推送的 binlog 并解析成结构化的事件对象,再提供给客户端或直接投递到消息队列。在 Debezium 与 Flink CDC 普及之前,它是国内使用较多的 CDC 方案。

工作原理与组成

Canal 由 server 与 client 两部分组成:server 负责与 MySQL 建立复制连接、解析日志、维护位点;client 通过 TCP 拉取数据。一个 server 可以配置多个 instance,每个 instance 对应一个 MySQL 实例的订阅。位点需要落盘或存入外部存储,否则重启后会从上次记录的位置重新开始,造成重复或缺口。

基本信息

定位MySQL binlog 增量订阅与解析组件
原理模拟从库发送 dump 协议,接收 binlog 并解析
输出Entry / RowChange(行级增删改)
投递TCP 客户端拉取,或直接投递 Kafka、RocketMQ 等
前置源库 binlog_format=ROW,并为 Canal 分配独立 slaveId

关键概念读法

概念含义注意
instance一个订阅实例,对应一个 MySQL 实例实例越多,server 端资源占用越高
slaveId伪装从库时使用的编号不得与真实从库冲突,否则复制报错
Entry解析出的日志事件包装对象包含事务头、行变更、DDL 等类型
RowChange一条行级增删改事件按行格式日志解析得到
位点已解析到的 binlog 位置必须持久化,否则重启后重复或漏数

典型使用场景

  • 业务库变更同步到数仓:把订单、用户表的变更持续投递到消息队列
  • 缓存与检索更新:变更事件触发缓存失效或索引重建
  • 历史存量同步:配合全量导出工具完成开荒,再用 Canal 追平增量
  • 多下游分发:解析一次、投递到消息队列,多个消费方各取所需
  • 审计留痕:把变更事件长期保存,支持事后追溯

数据流向

数据流向
# 源端:MySQL 需开启 binlog 且格式为 ROW
MySQL Master
  →(dump 协议持续推送 binlog)
Canal Server:解析为 Entry / RowChange,维护位点
  →(TCP 拉取或投递消息队列)
Canal Client / Kafka → 下游:数仓 ODS、缓存、检索索引、审计归档
Canal 只负责「把变更取出来」,不负责写入目标:落库由客户端或下游消费程序完成,因此幂等、重试与顺序处理仍要在消费侧实现。
位点持久化是 Canal 的生命线:位点丢失后只能重新指定起点,向前会重复消费、向后会造成永久缺口,两者都需要人工核对补数。

易错点

  • 给 Canal 分配的 slaveId 与真实从库冲突,导致复制报错或采集异常
  • 直连写入量大的主库而不做限流与资源评估,采集高峰挤压业务写入
  • 位点未做持久化或保存位置不当,重启后重复消费或漏数,需要人工比对补数
  • 下游消费只处理 insert 与 update,忽略 delete 事件,目标端长期残留已删除数据

数据来源与参考

  • Canal 官方文档(alibaba/canal 原理与架构)
  • Canal GitHub Wiki
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌