Canal:超详细部署与使用教程
Canal(译意为「水道/管道/沟渠」)是阿里巴巴开源的 MySQL 数据库增量日志解析组件,基于 MySQL binlog 实现增量数据订阅与消费,可用于数据库镜像、实时备份、索引构建、缓存刷新、异构数据同步等场景。
| 所属公司 | GitHub 仓库 | 官方文档/官网 | 开源协议 | Star 数 | 最新版本(截至 2026-10-27) | 主要语言 |
|---|---|---|---|---|---|---|
| 阿里巴巴(开源) | github.com/alibaba/canal | 官方文档均在 GitHub Wiki:github.com/alibaba/canal/wiki | Apache-2.0 | 约 30k | canal-1.1.8 | Java |
目录
一、项目概述
1.1 项目定位
早期阿里巴巴因杭州与美国双机房部署,需要跨机房数据同步,最初通过业务 trigger 获取增量变更;2010 年起改为直接解析数据库日志获取增量,由此衍生出大量数据库增量订阅与消费业务,Canal 即源于此。Canal 本身是一个MySQL binlog 增量订阅&消费组件:它模拟 MySQL slave 的交互协议,伪装成 slave 向 master 发送 dump 协议,接收并解析 binary log,再以 protobuf 3.0 协议提供给下游 client 消费。
当前 Canal 支持的源端 MySQL 版本:5.1.x、5.5.x、5.6.x、5.7.x、8.0.x(官方 README 说明)。
1.2 核心功能
- binlog 增量订阅与解析:伪装成 MySQL slave,拉取并解析 ROW 模式 binlog,还原 INSERT/UPDATE/DELETE 事件。
- 增量订阅消费的典型业务:数据库镜像、数据库实时备份、索引构建与实时维护(拆分异构索引、倒排索引)、业务 cache 刷新、带业务逻辑的增量数据处理。
- client-server 模式:server 与 client 之间使用 protobuf 3.0 协议,client 可用多种语言实现(官方提供 Java 客户端,社区有 C# CanalSharp、Go canal-go、PHP、Python、Rust、Node.js 客户端)。
- 消息投递集成:原生支持将变更投递到 Kafka / RocketMQ(1.1.x 起),借助 MQ 的多语言与削峰能力消费。
- 阿里云 RDS 订阅:原生支持阿里云 RDS for MySQL 的 binlog 订阅(含自动主备切换、OSS binlog 离线解析)。
- Canal Admin(1.1.4 起):引入 canal-admin 工程,提供 WebUI 动态管理能力——在线配置、Instance 任务管理、日志白屏运维。
- Prometheus 监控:1.1.x 起原生支持 Prometheus 指标暴露。
- Docker 镜像:1.1.x 起官方提供 Docker 镜像。
1.3 工作原理
Canal 的工作原理建立在 MySQL 主备复制原理之上:
- MySQL master 将数据变更写入二进制日志(binary log,记录叫做 binary log events,可通过
show binlog events查看); - MySQL slave 将 master 的 binary log events 拷贝到自己的中继日志(relay log);
- MySQL slave 重放 relay log 中的事件,反映到自己的数据上。
Canal 做的事:
- 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave,向 MySQL master 发送 dump 协议;
- MySQL master 收到 dump 请求后,开始推送 binary log 给 slave(即 canal);
- Canal 解析 binary log 对象(原始为 byte 流),转换为统一的消息结构供 client 消费。

整体组件结构:Canal 部署包中 instance 是核心单元,每个 instance 对应一个数据源订阅任务(默认 example);server 负责与 client 的交互与调度;parse 负责 binlog 解析;sink/store 负责事件投递与缓冲。
二、环境要求
| 项目 | 要求 |
|---|---|
| 操作系统 | Linux 推荐(生产);macOS / Windows 可用于开发测试 |
| JDK | JDK 8 及以上(Canal 为 Java 应用) |
| 源端 MySQL | 5.1.x / 5.5.x / 5.6.x / 5.7.x / 8.0.x;必须开启 binlog,且 binlog-format=ROW |
| MySQL 账号 | 需有 REPLICATION SLAVE、REPLICATION CLIENT 权限 |
| 网络 | Canal 机器需能访问 MySQL 的 3306;client 需能访问 Canal Server(默认 11111 端口) |
| 中间件(可选) | 集群模式需要 ZooKeeper;投递 Kafka/RocketMQ 需对应 MQ 集群;Canal Admin 需要 MySQL(存储元数据) |
| 硬件 | 单实例测试 1C2G 可跑;生产按 binlog 流量评估,建议 2C4G 起步 |
关键前提:源端 MySQL 的
my.cnf必须配置log-bin=mysql-bin、binlog-format=ROW、server_id=1(该 server_id 不能与 canal 的 slaveId 重复)。
三、部署方式
下面给出:压缩包部署(标准方式)→ Docker 部署 → Canal Admin WebUI 管理端部署 → Kafka/RocketMQ 投递对接。
3.1 方式一:压缩包部署(标准方式)
步骤 0:准备源端 MySQL
修改 my.cnf:
[mysqld]
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 主从复制需要的 server_id,勿与 canal slaveId 重复
重启 MySQL 后,创建并授权 canal 账号(官方 Wiki QuickStart):
CREATE USER canal IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
若使用阿里云 RDS for MySQL,默认已开启 binlog 且账号默认具备 binlog dump 权限,可跳过此步。
步骤 1:下载解压
从 Release 页下载:github.com/alibaba/canal/releases,最新版本 canal-1.1.8,产物为 canal.deployer-1.1.8.tar.gz:
mkdir -p /opt/canal
cd /opt/canal
wget https://github.com/alibaba/canal/releases/download/canal-1.1.8/canal.deployer-1.1.8.tar.gz
tar zxvf canal.deployer-1.1.8.tar.gz
解压后目录结构:
bin/ # 启动/停止脚本
conf/ # 配置(canal.properties 全局配置 + example/instance.properties 实例配置)
lib/ # 依赖
logs/ # 日志
步骤 2:修改实例配置
编辑 conf/example/instance.properties(官方 QuickStart 给出的最小配置项):
## 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 =
# username/password:改成自己的数据库信息
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal
canal.instance.defaultDatabaseName =
canal.instance.connectionCharset = UTF-8
# table regex:只订阅指定库表(默认 .*\..* 即全部)
canal.instance.filter.regex = .*\..*
说明:
canal.instance.connectionCharset对应 Java 编码类型(UTF-8 / GBK / ISO-8859-1);单 CPU 机器需将canal.instance.parser.parallel设为false。
全局配置 conf/canal.properties 中常用项:
| 配置项 | 说明 | 默认值 |
|---|---|---|
canal.destinations |
本 server 包含的 instance 列表 | example |
canal.port |
server 提供给 client 的端口 | 11111 |
canal.zkServers |
集群模式 ZooKeeper 地址(单机留空) | 空 |
canal.serverMode |
投递模式:tcp / kafka / rocketMQ / rabbitMQ | tcp |
步骤 3:启动与停止
sh bin/startup.sh
# 停止
sh bin/stop.sh
步骤 4:验证启动成功
# 查看 server 日志,出现以下内容即成功
tail -f logs/canal/canal.log
# 期望输出:
# INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## the canal server is running now ......
# 查看 instance 日志
tail -f logs/example/example.log
# 期望输出:
# INFO c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start successful....
3.2 方式二:Docker 部署
官方 Wiki 提供 Docker QuickStart。示例:
docker run -d --name canal \
-p 11111:11111 \
-v /opt/canal/conf:/home/admin/canal/conf \
canal/canal-server:v1.1.8
镜像 tag 与 release 对应(以官方 Wiki「Docker QuickStart」为准);生产建议挂载
conf目录替换配置。
3.3 方式三:Canal Admin WebUI 管理端(1.1.4+,推荐生产)
Canal Admin 是面向 WebUI 的动态管理端,可在线管理集群、Server、Instance 与日志。
步骤 1:部署 canal-admin
从 Release 页下载 canal.admin-1.1.8.tar.gz,其元数据需要 MySQL(先执行官方 Wiki 给出的 canal_admin.sql 建表脚本),然后配置 conf/application.yml 中的数据源后启动:
sh bin/startup.sh
# 默认 Web 端口 8089(以官方 Wiki Canal-Admin-Guide 为准)
步骤 2:配置被管的 canal server
被管的 canal server 在 canal.properties 中接入 admin:
canal.admin.manager = 127.0.0.1:8089
canal.admin.port = 11110
canal.admin.user = admin
canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D61502944
步骤 3:WebUI 操作
浏览器登录 admin 后,可在「Canal Server → 集群管理」中新建集群(填写集群名称 + ZooKeeper 地址),在「Server 管理 / Instance 管理」中动态创建与启停订阅任务。

3.4 方式四:对接 Kafka / RocketMQ 投递
修改 canal.properties 切换投递模式:
canal.serverMode = rocketMQ # 或 kafka
canal.mq.servers = 127.0.0.1:9876
并在 instance.properties 指定目标 topic:
canal.mq.topic = example_topic
# 按库表路由时可指定 partition 规则(以官方 Wiki Canal-Kafka-RocketMQ-QuickStart 为准)
重启后,binlog 变更事件将直接投递到 MQ,下游消费方只需订阅 MQ,无需再直连 Canal Server。
3.5 验证部署成功(通用)
logs/canal/canal.log出现the canal server is running now;logs/example/example.log出现start successful;- 在源端 MySQL 对订阅表执行
INSERT,client 端(见 4.1)能收到对应变更消息。
四、使用方法
4.1 基础用法:Java 客户端消费
官方 Wiki 提供 client 示例(CanalConnector API):
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.Message;
import com.alibaba.otter.canal.protocol.CanalEntry;
import java.net.InetSocketAddress;
public class CanalClientDemo {
public static void main(String[] args) {
// 连接 canal server,订阅 example 实例的全部表
CanalConnector connector = CanalConnectors.newSingleConnector(
new InetSocketAddress("127.0.0.1", 11111),
"example", "", "");
connector.connect();
connector.subscribe(".*\\..*");
connector.rollback();
while (true) {
Message message = connector.getWithoutAck(100); // 拉取 100 条
long batchId = message.getId();
if (batchId == -1 || message.getEntries().isEmpty()) {
try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
continue;
}
for (CanalEntry.Entry entry : message.getEntries()) {
if (entry.getEntryType() == CanalEntry.EntryType.ROWDATA) {
// 解析 RowChange 事件,按需处理 INSERT/UPDATE/DELETE
System.out.println(entry.toString());
}
}
connector.ack(batchId); // 确认消费
}
}
}
引入依赖(官方 README):
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>1.1.8</version>
</dependency>
4.2 常用命令/操作
# 启动 / 停止 / 重启
sh bin/startup.sh
sh bin/stop.sh
# 查看日志
tail -f logs/canal/canal.log # server 主日志
tail -f logs/example/example.log # example 实例日志
# 源端确认 binlog 状态
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';
SHOW MASTER STATUS;
4.3 进阶功能
- 多实例订阅:在
canal.destinations中配置多个 instance(如example,order_db),每个实例独立配置conf/<dest>/instance.properties。 - 表/库过滤:
canal.instance.filter.regex用正则精确订阅(如order_db\.\*),减少无用事件。 - 集群高可用:配合 ZooKeeper,同一 destination 部署多节点,同一时刻只有一个节点工作,宕机自动切换(官方 Wiki AdminGuide)。
- Prometheus 监控:1.1.x 原生支持,暴露指标供 Prometheus 采集(官方 Wiki「Prometheus QuickStart」)。
- 多语言客户端:Go(canal-go)、C#(CanalSharp)、Python、PHP、Rust、Node.js 客户端均可直接 tcp 模式消费。
4.4 适用场景
- MySQL 到异构存储的实时同步(ES 索引、Redis 缓存、数仓);
- 数据库实时备份/灾备;
- 业务 cache 刷新(订单变更后自动清缓存);
- 拆库拆表后的数据归并;
- 数据审计与变更事件驱动(CDC,Change Data Capture)。
五、常见问题排查(FAQ)
Q1:instance 日志报 ERROR: You are not using binary logging 或 could not find first log file
- 原因:源端 MySQL 未开启 binlog,或 binlog-format 不是 ROW。
- 解决:按「环境要求」修改 my.cnf(log-bin=mysql-bin + binlog-format=ROW)并重启 MySQL。
Q2:报 Access denied; you need (at least one of) the REPLICATION SLAVE privilege(s) for this operation
- 原因:canal 账号权限不足。
- 解决:GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; FLUSH PRIVILEGES;
Q3:启动后 example.log 一直卡在 subscribe ...,无数据
- 原因:① 源端没有写入;② canal.instance.filter.regex 过滤掉了目标表;③ position 从很久以前的位点开始,正在追 binlog。
- 解决:先在源端对订阅表 INSERT 测试;确认 regex 正确(默认 .*\..*);观察日志追位点进度。
Q4:client 收不到数据,但 getWithoutAck 返回空
- 原因:尚未 subscribe,或未先 rollback 重置;批量拉取参数过小。
- 解决:确认调用了 connector.subscribe(".*\\..*");参考 4.1 示例先 rollback() 再循环拉取。
Q5:canal.instance.mysql.slaveId 与 MySQL server_id 冲突报错
- 原因:canal 伪装的 slaveId 与主库或已有 slave 重复。
- 解决:把 canal.instance.mysql.slaveId 改成未占用的值(如 1234)。
Q6:MySQL 8.0 连接报认证插件错误(caching_sha2_password)
- 原因:MySQL 8 默认认证插件,老版本 canal 驱动不支持。
- 解决:升级到 1.1.5+ 版本;或对 canal 账号 ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';。
Q7:单 CPU 机器解析卡住或报错
- 解决:官方 Wiki 明确要求单 CPU 机器将 canal.instance.parser.parallel 设为 false。
六、部署注意事项与最佳实践
- 生产用 ROW 模式:STATEMENT 模式无法可靠还原行变更,一律 ROW;大表 DDL 会产生大事务,评估 binlog 体积。
- slaveId 唯一:canal 模拟 slave,slaveId 不能与源库 server_id 及其他 slave 重复。
- 不要用 root 直连:专用 canal 账号,最小权限(SELECT + REPLICATION 权限)。
- 过滤精准化:用
canal.instance.filter.regex只订阅需要的库表,减少解析与网络开销。 - 消费必须 ack:client 处理完务必
ack(batchId),否则会重复拉取;处理失败时rollback重试。 - 集群必配 ZooKeeper:单节点 deployer 挂了就停更,生产用 ZK 做主备切换。
- 大数据量走 MQ:tcp 直连适合小流量;流量大、下游多,用 RocketMQ/Kafka 模式解耦。
- 监控纳入 Prometheus:1.1.x 原生支持,关注解析延迟与积压。
七、参考资料
- GitHub 仓库:https://github.com/alibaba/canal
- Wiki 首页:https://github.com/alibaba/canal/wiki/Home
- QuickStart:https://github.com/alibaba/canal/wiki/QuickStart
- Docker QuickStart:https://github.com/alibaba/canal/wiki/Docker-QuickStart
- Canal Kafka/RocketMQ QuickStart:https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart
- Canal Admin 指南:https://github.com/alibaba/canal/wiki/Canal-Admin-Guide
- Prometheus 监控:https://github.com/alibaba/canal/wiki/Prometheus-QuickStart
- 阿里云 RDS 订阅:https://github.com/alibaba/canal/wiki/aliyun-RDS-QuickStart
- Client API:https://github.com/alibaba/canal/wiki/ClientAPI
- FAQ:https://github.com/alibaba/canal/wiki/FAQ
- Release 下载:https://github.com/alibaba/canal/releases