3. 主流CDC工具概览
选型CDC工具时,最容易犯的错误是只看“能不能采集MySQL”,而忽略采集之后数据往哪里去、以什么格式去、由谁负责容错。Debezium、Canal、Flink CDC、Maxwell这四款工具都能从MySQL binlog读取变更,但它们在架构定位、部署形态、下游生态和运维责任上差异明显。理解这些差异,比记住功能列表更重要。
四款工具的定位差异
Debezium是Kafka Connect生态中的一组Source Connector,本身不独立运行,而是作为Kafka Connect插件部署。它把MySQL、PostgreSQL、MongoDB、Oracle等数据库的变更事件写入Kafka Topic,事件结构包含before、after、source、op等字段,天然适合“变更即消息”的架构。Debezium依赖Kafka Connect的分布式模式和Offset存储,容错、扩缩容、重启恢复都由Connect框架承担。它的优势是数据库种类多、事件格式规范、与Kafka生态无缝;代价是必须引入Kafka和Connect集群,链路较长。
Canal是阿里开源的独立CDC服务,模拟MySQL Slave协议向主库或从库发送dump请求,解析binlog后推送到Kafka、RocketMQ或直接由客户端拉取。Canal Server独立部署,自带Instance管理,一个Instance对应一个数据库实例的采集任务。它的优势是轻量、部署简单、对MySQL协议理解深入;局限是主要面向MySQL,下游生态需要自行对接,Exactly-Once语义依赖下游消费端实现。
Flink CDC把CDC采集能力内置到Flink Source中,通过增量快照算法实现全量+增量一体化读取。它不依赖Kafka Connect,也不要求先落Kafka,可以直接在Flink作业中完成采集、转换、写入下游。Flink CDC支持MySQL、PostgreSQL、Oracle、MongoDB等,配合Flink的Checkpoint机制提供Exactly-Once。它的优势是链路短、流批一体、状态管理成熟;代价是必须运行Flink集群,作业开发需要Flink SQL或DataStream API能力。
Maxwell是轻量级MySQL binlog订阅工具,输出JSON格式变更事件到Kafka、Kinesis、RabbitMQ或stdout。它由Java编写,单进程运行,配置简单,适合快速搭建“MySQL到Kafka”的同步链路。Maxwell不提供分布式协调,高可用需要借助外部工具或自行实现,功能边界相对窄,但胜在简单直接。
功能边界的关键判断点
第一,是否要求先落Kafka。Debezium和Maxwell默认以Kafka为主要下游,Canal可以推Kafka也可以由客户端直接拉取,Flink CDC则完全不要求Kafka。如果团队已有Kafka且希望变更事件被多个消费者复用,Debezium和Canal更自然;如果希望采集后直接在流作业中完成清洗和写入,Flink CDC链路最短。
第二,全量+增量的处理方式。Debezium通过initial snapshot模式先做全量快照再切增量,快照期间需要锁表或使用一致性快照;Canal本身不负责全量,通常需要业务侧先做一次全量导出再启动增量;Flink CDC的增量快照算法支持无锁、并行、可断点续传的全量读取,这是它相对前两者的明显优势;Maxwell同样只做增量,全量需要另行处理。
第三,Exactly-Once的保障位置。Debezium依赖Kafka Connect的Offset提交和Kafka事务;Flink CDC依赖Flink Checkpoint和两阶段提交Sink;Canal和Maxwell本身不提供端到端Exactly-Once,需要下游消费端做幂等或去重。这一点直接决定故障恢复后是否会出现重复数据。
第四,运维复杂度。Maxwell最简单,单进程启动即可;Canal需要维护Server和Instance;Debezium需要维护Kafka Connect集群和Kafka;Flink CDC需要维护Flink集群、Checkpoint存储和作业管理。选型时要评估团队已有的基础设施,而不是只看工具本身。
适用场景对照
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| MySQL变更写入Kafka,供多消费者使用 | Debezium / Canal | 事件格式规范,Kafka生态成熟 |
| 实时数仓,采集后直接做ETL | Flink CDC | 全量+增量一体,流批统一 |
| 快速搭建MySQL到Kafka的轻量同步 | Maxwell | 单进程、配置少、上线快 |
| 多数据库异构采集 | Debezium / Flink CDC | 支持MySQL、PG、Oracle、MongoDB等 |
| 已有Flink集群,希望减少中间件 | Flink CDC | 无需额外维护Kafka Connect |
| 仅MySQL,且希望独立部署、不绑Flink | Canal | 独立Server,Instance粒度管理 |
选型时的实操建议
如果团队已经在使用Kafka Connect,并且需要把多种数据库的变更统一写入Kafka,Debezium是首选。它的配置以JSON为主,一个MySQL Connector的典型配置包括:
{
"name": "mysql-inventory-connector",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "mysql-primary",
"database.port": "3306",
"database.user": "debezium",
"database.password": "******",
"database.server.id": "184054",
"database.server.name": "inventory",
"database.include.list": "inventory",
"table.include.list": "inventory.orders,inventory.customers",
"database.history.kafka.bootstrap.servers": "kafka:9092",
"database.history.kafka.topic": "schema-changes.inventory",
"include.schema.changes": "true",
"snapshot.mode": "initial"
}
}
其中database.server.id必须全局唯一,不能与MySQL集群中已有Slave的server-id冲突;snapshot.mode设为initial表示先做全量快照再切增量,生产环境若表很大,需要评估快照对主库的压力,必要时改为schema_only或使用从库采集。
如果选择Flink CDC,核心是在Flink SQL中定义Source表并指定启动模式:
CREATE TABLE mysql_orders (
id BIGINT,
user_id BIGINT,
amount DECIMAL(10,2),
status STRING,
update_time TIMESTAMP(3),
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'mysql-primary',
'port' = '3306',
'username' = 'flinkcdc',
'password' = '******',
'database-name' = 'inventory',
'table-name' = 'orders',
'scan.startup.mode' = 'initial',
'server-time-zone' = 'Asia/Shanghai'
);
scan.startup.mode可选initial、latest-offset、timestamp等,initial表示先全量再增量。Flink CDC的增量快照会把全量阶段拆成多个chunk并行读取,并通过Checkpoint记录进度,作业失败重启后可以从上次Checkpoint继续,不会重复全量。
binlog_format=ROW、binlog_row_image=FULL,并确保采集账号具备REPLICATION SLAVE、REPLICATION CLIENT权限。Debezium和Flink CDC还需要访问information_schema读取表结构。这些前置条件不满足时,工具本身配置再正确也无法工作。
总结来看,Debezium强在生态和格式规范,Canal强在轻量和MySQL协议理解,Flink CDC强在全量增量一体和流批统一,Maxwell强在简单直接。选型的核心不是比较功能多少,而是看数据要从哪里来、到哪里去、由谁保证一致性、团队能维护什么基础设施。把这四个问题回答清楚,工具选择自然清晰。