1. Flink CDC 概述:从数据同步的痛点说起
做数据同步这么多年,我踩过不少坑。早期用 Sqoop 做离线同步,每天凌晨跑一次,业务方总抱怨数据延迟太大。后来尝试用 Canal 加 Kafka 做实时同步,架构倒是实时了,但维护成本高得吓人——Canal 挂了要手动重启,Kafka 集群要专人运维,写消费代码还得处理各种边界情况。
直到 Flink CDC 出现,我才觉得实时同步这件事终于「对味」了。说白了,它就是把数据库的变更日志(比如 MySQL 的 binlog、PostgreSQL 的 WAL)直接当成 Flink 的数据源来消费。你不需要再搭一套 Canal+Kafka 的中间链路,一个 Flink 作业就能搞定全量+增量同步。
一句话总结:Flink CDC = 数据库变更捕获 + Flink 流处理引擎,让你用 SQL 就能定义实时同步任务。
1.1 什么是 CDC?
CDC(Change Data Capture,变更数据捕获)是一种技术模式。它的核心思想是:监听数据源的变更事件,实时捕获这些变更,然后同步到目标系统。
举个例子。你在 MySQL 里执行了一条 UPDATE 语句,把用户张三的余额从 100 改成了 200。CDC 工具会捕获这条变更,生成一条包含「变更前数据」和「变更后数据」的事件,然后推送给下游消费者。
CDC 的实现方式主要有两种:
- 基于查询的 CDC:定期轮询源表,通过时间戳或自增 ID 判断哪些数据发生了变化。这种方式延迟高,对数据库有压力,而且无法捕获删除操作。
- 基于日志的 CDC:直接读取数据库的事务日志(如 MySQL binlog、PostgreSQL WAL、Oracle Redo Log)。这种方式延迟低(毫秒级),对源库无侵入,能捕获所有 DML 操作。
我个人习惯把基于日志的 CDC 称为「真正的 CDC」。为什么?因为只有它才能做到实时、完整、无侵入。我在项目中遇到过用查询式 CDC 做订单同步,结果因为时间戳精度不够,漏掉了同一秒内的两条更新——这种问题排查起来特别痛苦。
1.2 CDC 技术选型对比
市面上 CDC 工具不少,我列几个常用的,咱们对比着看。
| 特性 | Canal | Debezium | Flink CDC |
|---|---|---|---|
| 支持数据源 | MySQL(主要) | MySQL、PostgreSQL、MongoDB、Oracle 等 | MySQL、PostgreSQL、MongoDB、Oracle、SqlServer 等 |
| 消费方式 | 客户端订阅 | Kafka Connect | Flink DataStream / SQL |
| 全量+增量 | 需额外开发 | 支持(Snapshot + Streaming) | 原生支持,自动切换 |
| 断点续传 | 需自行维护 offset | 依赖 Kafka offset | Flink Checkpoint 原生支持 |
| 数据转换 | 客户端处理 | Kafka Streams / 自定义 | Flink SQL / DataStream API |
| 运维复杂度 | 中(需部署 Canal Server) | 高(需部署 Kafka + Kafka Connect) | 低(Flink 作业即可) |
你可能会问:既然 Debezium 也能做 CDC,为什么还要用 Flink CDC?
嗯,这里有个关键区别。Debezium 本质上是一个 Kafka Connect 的 Source Connector,它把变更事件写入 Kafka,然后你需要自己写 Flink 作业去消费 Kafka。而 Flink CDC 把 Debezium 的底层能力封装成了 Flink 的 Source 接口,你直接在 Flink 里就能消费 binlog,不需要中间经过 Kafka。
说白了,Flink CDC = Debezium 的捕获能力 + Flink 的计算能力。少了一层 Kafka,延迟更低,架构更简洁。
1.3 Flink CDC 核心优势
我总结了四个核心优势,这也是我在项目中坚持用 Flink CDC 的原因。
- 全量+增量一体化:传统做法是先做全量同步,再切到增量同步,中间需要手动对齐偏移量。Flink CDC 自动完成这个切换,你只需要写一条 SQL。我记得第一次用的时候还不太放心,特意看了源码——嗯,它确实在底层做了锁表和快照的协调。
- 断点续传,Exactly-Once 语义:Flink 的 Checkpoint 机制保证了数据不丢不重。作业挂了重启,从上次 Checkpoint 恢复,binlog 的偏移量也一起恢复了。这个能力在线上环境太重要了,我曾经因为网络抖动导致 Canal 丢过数据,排查了一整天才发现。
- SQL 化开发:用 Flink SQL 定义 CDC 同步任务,代码量减少 80%。比如从 MySQL 同步到 Kafka,一条 INSERT INTO 语句就搞定了。团队里的 Java 初级工程师也能快速上手。
- 丰富的下游生态:Flink 支持 Kafka、Elasticsearch、HBase、ClickHouse、Doris 等几十种 Connector。CDC 捕获的数据可以直接写入这些系统,不需要额外开发。
我的建议:如果你的团队已经用了 Flink,那 Flink CDC 是首选。如果团队没有 Flink 技术栈,但需要做 CDC,可以考虑 Debezium + Kafka 的方案。不过我个人还是推荐 Flink CDC,因为它的生态和社区发展速度太快了。
1.4 Flink CDC 应用场景
我挑几个典型的场景说说,都是我在实际项目中遇到过的。
- 实时数据仓库:把 MySQL 的业务数据实时同步到 ClickHouse 或 Doris,构建实时数仓。我做过一个电商项目,订单数据从 MySQL 同步到 ClickHouse,延迟控制在 3 秒以内,支持实时大屏和实时报表。
- 缓存与索引更新:数据库变更后,实时更新 Redis 缓存或 Elasticsearch 索引。比如商品信息变更后,自动刷新 ES 中的搜索索引,保证搜索结果的时效性。
- 微服务间数据同步:多个微服务共享同一份数据,通过 CDC 实现数据最终一致性。我曾经帮一个金融项目做过账户系统的数据同步,避免了双写带来的数据不一致问题。
- 数据库迁移与异构复制:从 MySQL 迁移到 PostgreSQL,或者从自建数据库迁移到云数据库。Flink CDC 支持 Schema 变更的同步,迁移过程可以做到业务无感知。
- 实时数据清洗与转换:在同步过程中对数据进行脱敏、格式转换、字段映射。比如把手机号脱敏后再写入目标库,用 Flink SQL 的 UDF 就能实现。
避坑指南:我曾经在 MySQL 5.6 上使用 Flink CDC,发现 binlog 格式必须设置为 ROW,否则无法捕获完整的变更数据。另外,如果源表没有主键,Flink CDC 的全量同步阶段会报错——这是 Debezium 的限制,Flink CDC 继承了这一点。所以建表时一定要加主键。
1.5 Flink CDC 核心架构图
下面这张图展示了 Flink CDC 的整体架构。我画的时候特意把数据流和组件关系标清楚了,你一看就明白。
从架构图可以看出,Flink CDC 的核心是把 Debezium 的捕获能力嵌入到 Flink 的 Source 接口中。上层用 Flink SQL 或 DataStream API 定义同步逻辑,底层自动处理全量快照、增量日志、断点续传这些复杂逻辑。
嗯,这一章的内容就到这里。CDC 的概念、选型对比、Flink CDC 的优势和场景,我都用自己的经验串了一遍。后面的章节我们会深入每个细节,包括环境搭建、核心 API、高级特性、性能调优和实战案例。准备好了吗?我们继续。