3. Flink CDC Connector 介绍

好,咱们进入第三章。这一章我打算聊聊 Flink CDC Connector——说白了,它就是 Flink 用来对接各种数据库变更数据捕获的官方连接器。我记得刚接触 CDC 那会儿,市面上方案挺杂的,Canal、Debezium、Maxwell 各搞各的,集成起来挺费劲。Flink CDC 出来之后,事情简单了不少。

3.1 Flink CDC Connector 是什么

Flink CDC Connector 是 Apache Flink 官方提供的一组 Source 连接器。它的核心能力就一个:把数据库的变更事件(INSERT、UPDATE、DELETE)实时地拉进 Flink 流里。

你想想看,传统做法是写个定时任务去扫表,或者用触发器搞个中间表。这些方式要么延迟高,要么对业务库有侵入。Flink CDC 直接解析数据库的 binlog(MySQL)或 WAL(PostgreSQL),变更一发生,Flink 这边就收到了。

一句话总结:Flink CDC Connector = 数据库变更事件的实时采集器 + Flink 流式 Source。

我个人习惯把它当作「流式 JDBC」来理解。JDBC 是查一次拿一个快照,CDC 是持续监听,每次变更都推给你。这两种模式在实时管道里经常配合使用,后面会细讲。

3.2 支持的数据库

截至当前版本,Flink CDC 官方支持的数据库如下表。我列了个清单,方便你对照选型:

数据库 连接器名称 底层依赖 我的使用建议
MySQL mysql-cdc Debezium + Binlog 最成熟,生产首选
PostgreSQL postgres-cdc Debezium + WAL 适合 PG 生态,注意 wal_level
MongoDB mongodb-cdc Debezium + Oplog/Change Stream 文档型变更,注意 oplog 大小
Oracle oracle-cdc Debezium + LogMiner 企业级场景,需 DBA 配合开归档
SqlServer sqlserver-cdc Debezium + CDC Table 微软生态,配置稍复杂
Db2 db2-cdc Debezium + ASN Capture 大型机场景,用得少
TiDB tidb-cdc TiKV CDC 国产分布式,兼容 MySQL 协议

嗯,这里要注意:MySQL 和 PostgreSQL 是社区最活跃、坑最少的两个。我在项目中遇到过一个 Oracle 的坑——LogMiner 在归档日志切换频繁时会有性能抖动,后来加了参数调优才稳住。如果你刚上手,建议先从 MySQL 开始。

3.3 核心特性:断点续传

断点续传,说白了就是「任务挂了重启,能从上次中断的地方继续消费,不丢数据,不重复消费」。这个特性在实时管道里是刚需。

Flink CDC 怎么做到的?它把消费进度(binlog 的偏移量、LSN 号)保存在 Flink 的 状态后端 里。配合 Flink 的 Checkpoint 机制,定期把偏移量快照下来。任务重启时,从最近一次成功的 Checkpoint 恢复,CDC Source 就拿着那个偏移量重新连接数据库,接着读。

我的经验:Checkpoint 间隔别设太短,默认 3 秒够用。太短了频繁快照,对状态后端压力大;太长了恢复时重复数据多。我曾经设过 10 秒,结果一次故障恢复了 8 秒的数据重复,下游去重逻辑差点扛不住。

断点续传的配置很简单,核心就两个参数:

-- 启用 Checkpoint(必须)
env.enableCheckpointing(5000)  -- 5 秒一次

-- CDC Source 配置(以 MySQL 为例)
tableName = "your_db.your_table"
serverId = "5401-5404"  -- 多并行度时分配多个 serverId
scan.startup.mode = "initial"  -- 从当前位点开始

这里有个容易踩的坑:MySQL 的 server-id 必须全局唯一。如果你多个 CDC 任务连同一个 MySQL 实例,server-id 冲突会导致 binlog 拉取异常。我曾经在测试环境吃过这个亏,两个任务用同一个 server-id,结果一个任务老是断连,排查了半天。

3.4 核心特性:全量 + 增量

这是 Flink CDC 最让我觉得「真香」的特性。传统 CDC 方案,全量同步和增量同步是两套逻辑:全量用 JDBC 扫表,增量用 binlog 监听。你得自己写代码做衔接,还要保证数据不丢不重。

Flink CDC 把这两步合二为一了。它内部的处理流程是这样的:

  1. 先做全量快照:用 SELECT 把表里现有数据全部读出来,发往下游。
  2. 无缝切换增量:全量读完后,自动切换到 binlog 监听模式,只消费变更事件。
  3. 全量期间的增量不丢:在全量扫描期间,binlog 的变更会被缓存起来,等全量结束后再回放。

你想想看,这个设计多巧妙。以前我们要自己维护一个「水位线」,全量读到哪条记录,增量从哪个位点开始。Flink CDC 内部用了一个 chunk 分片算法,把表按主键拆成多个小 chunk,每个 chunk 独立做快照,同时记录该 chunk 对应的 binlog 位点。全量结束后,所有 chunk 的位点对齐,增量就从那个对齐点开始。

注意:全量 + 增量模式要求表必须有主键。没有主键的表,Flink CDC 会退化成纯增量模式,全量阶段只能扫一次,后续变更靠 binlog。我建议生产环境所有 CDC 表都加上主键,否则数据一致性很难保证。

下面这张图展示了全量 + 增量的完整流程:

Flink CDC 全量 + 增量流程 MySQL 数据库 Binlog + 数据表 全量快照 (SELECT) 增量监听 (Binlog) Chunk 分片引擎 按主键拆成 N 个 Chunk Binlog 位点对齐 Flink 状态后端 DataStream 输出 全量数据 + 增量事件 说明: 全量快照期间产生的增量变更会被缓存,等全量结束后再回放,保证数据不丢不重。

全量 + 增量这个特性,在实际项目中帮了大忙。我记得有一次做电商订单表的实时同步,表里有 2 亿条历史数据。如果用传统方案,全量同步得跑好几个小时,期间产生的增量还得单独处理。Flink CDC 一把梭,全量跑完自动切增量,中间没有任何人工介入。嗯,真省心。

3.5 核心特性总结

我把 Flink CDC 的三个核心特性再捋一遍:

  • 断点续传:基于 Flink Checkpoint 保存消费位点,任务重启自动恢复,不丢不重。
  • 全量 + 增量:一次配置,自动完成全量扫描和增量监听的无缝切换。
  • Chunk 分片:按主键拆片并行读取,全量阶段也能利用多并行度提升吞吐。

这三个特性加在一起,让 Flink CDC 成了实时数据管道里最趁手的工具之一。你不需要再自己维护位点、不需要写两套代码、不需要担心全量和增量的衔接问题。开箱即用,说的就是它。

一个小建议:刚开始用 Flink CDC 时,先在测试环境跑一个小表(几千条数据),验证全量 + 增量切换是否正常。然后模拟一次任务重启,看看断点续传是否生效。这两个验证通过了,再上生产大表。我见过太多人一上来就跑亿级大表,出了问题排查半天,其实小表验证只需要几分钟。