3. CDC入湖链路架构设计:Source端选型、中间件选型、Sink端适配
CDC入湖链路,说白了就是一条数据管道。源头是数据库,中间是捕获工具,终点是湖存储。这三段选不对,后面元数据管控做得再好也白搭。我见过太多项目,Source端选了个不合适的版本,结果天天丢数据,最后整个链路重做。
今天咱们就把这三段掰开揉碎了讲。我会结合自己踩过的坑,告诉你每个环节到底该怎么选。
3.1 Source端选型:MySQL / Oracle / PostgreSQL
Source端选型,核心看三点:日志格式、权限要求、版本兼容性。我习惯先问一个问题——你的数据库版本是多少?
| 数据库 | 日志机制 | CDC支持方式 | 版本要求 | 个人建议 |
|---|---|---|---|---|
| MySQL | Binlog (Row格式) | Debezium / Canal | 5.7+ (推荐8.0+) | 最成熟,坑最少 |
| Oracle | Redo Log / LogMiner | Debezium (LogMiner) | 11g+ (推荐19c+) | 注意归档日志空间 |
| PostgreSQL | WAL (Logical Replication) | Debezium (pgoutput) | 10+ (推荐14+) | 逻辑复制槽要监控 |
核心原则:Source端必须开启完整日志模式。MySQL要设置 binlog_format=ROW 且 binlog_row_image=FULL。Oracle要开启 ARCHIVELOG 和 SUPPLEMENTAL LOG。PostgreSQL要设置 wal_level=logical。
MySQL选型要点:
- 我个人习惯用8.0版本,因为8.0的Binlog压缩功能能省不少磁盘。5.7也能用,但记得检查
server_id不能重复。 - 权限方面,CDC账号需要
REPLICATION SLAVE和REPLICATION CLIENT。别给多了,也别给少了。 - 避坑指南:我曾经遇到一个案例,MySQL主库Binlog保留时间只有1小时,CDC任务一重启,Binlog已经清掉了,数据全丢。所以
expire_logs_days至少要设7天。
Oracle选型要点:
- Oracle的CDC比较特殊,Debezium用的是LogMiner方式。这意味着你要额外关注归档日志的存储空间。
- 我建议用19c版本,因为12c之后的
PDB模式在CDC时会有一些坑,19c修复了不少。 - 权限上,需要
SELECT ANY TRANSACTION、LOGMINING和FLASHBACK权限。嗯,这里要注意,DBA权限虽然方便,但生产环境不建议。
PostgreSQL选型要点:
- PostgreSQL的CDC依赖逻辑复制槽。逻辑复制槽有个问题——如果消费者挂了,WAL日志会一直堆积,直到磁盘爆掉。
- 我建议用14+版本,因为14引入了
pg_stat_replication_slots视图,方便监控复制槽状态。 - 避坑指南:我曾经在生产环境遇到过复制槽失效导致WAL堆积,磁盘直接打满。从那以后,我每次部署都会加一个监控告警,复制槽延迟超过1小时就报警。
3.2 中间件选型:Debezium / Canal / DataX
中间件是CDC链路的核心。选哪个,取决于你的技术栈和团队能力。我三个都用过,说说我的真实感受。
| 中间件 | 原理 | 支持数据源 | 输出格式 | 适用场景 |
|---|---|---|---|---|
| Debezium | Kafka Connect Connector | MySQL / Oracle / PG / MongoDB / SQL Server | Avro / JSON / Protobuf | 实时流、多数据源、Kafka生态 |
| Canal | 模拟MySQL Slave协议 | MySQL (阿里RDS兼容) | JSON / Protobuf | 纯MySQL、低延迟、轻量级 |
| DataX | 离线批量拉取 | MySQL / Oracle / PG / HDFS / Hive | 无固定格式 | 离线批量、全量同步、异构迁移 |
我的选择建议:如果团队熟悉Kafka生态,无脑选Debezium。如果只是MySQL到Hudi,且延迟要求高,Canal更轻量。如果是离线全量同步,DataX最稳。
Debezium深度解析:
- Debezium本质上是Kafka Connect的一个Connector。它把数据库的变更事件转换成Kafka消息。
- 我习惯用Debezium 2.x版本,因为2.x支持了增量快照(Incremental Snapshot),不用再停写做全量快照了。
- 配置上,核心参数是
snapshot.mode。我建议用when_needed模式,这样Debezium会在需要时自动做快照。 - 避坑指南:我曾经遇到Debezium在Oracle上频繁OOM。后来发现是
max.queue.size设太大,改成8192就好了。你想想看,队列太大,内存扛不住。
Canal深度解析:
- Canal是阿里巴巴开源的,专门针对MySQL。它模拟MySQL Slave协议拉取Binlog。
- 我建议用Canal 1.1.6+版本,因为1.1.6修复了多个Binlog解析的bug。
- Canal的优点是延迟极低,毫秒级。缺点是只支持MySQL,而且对阿里云RDS兼容性最好。
- 我个人习惯用Canal做MySQL到Kafka的实时同步,然后Kafka再接Flink做入湖。
DataX深度解析:
- DataX是离线同步工具,不是实时CDC。但它在全量同步阶段非常有用。
- 我建议用DataX做首次全量数据迁移,然后用Debezium或Canal做增量同步。
- DataX的优点是稳定、支持的数据源多。缺点是速度受限于单机性能。
- 避坑指南:我曾经用DataX同步Oracle到HDFS,结果因为Oracle的字符集问题,中文全变成了乱码。后来加了
encoding=UTF-8参数才解决。
3.3 Sink端适配:Hudi / Iceberg / Delta Lake
Sink端是数据入湖的最后一公里。选哪个湖格式,决定了你的数据怎么查、怎么更新、怎么管理。我三个都深度用过,说说我的看法。
| 湖格式 | 核心能力 | 写入模式 | 查询引擎 | 适用场景 |
|---|---|---|---|---|
| Apache Hudi | 增量查询、Upsert、Clustering | Copy-on-Write / Merge-on-Read | Spark / Flink / Presto / Hive | 实时入湖、更新频繁、增量ETL |
| Apache Iceberg | ACID事务、Schema Evolution、分区演进 | Copy-on-Write / Merge-on-Read | Spark / Flink / Trino / Hive | 数据湖仓、多引擎、强一致性 |
| Delta Lake | ACID事务、Time Travel、Schema Enforcement | Copy-on-Write | Spark / Presto / Hive | Databricks生态、Spark为主 |
核心原则:Sink端选型要看你的查询引擎和更新模式。如果主要用Spark,Delta Lake最顺手。如果多引擎混用,Iceberg最灵活。如果实时入湖且更新频繁,Hudi最合适。
Hudi适配要点:
- Hudi的Upsert能力是三个里面最强的。它支持基于记录键的更新和删除。
- 我建议用Hudi 0.13+版本,因为0.13引入了Metadata Table的改进,查询性能提升明显。
- 写入模式上,我习惯用Merge-on-Read。虽然查询时会有合并开销,但写入延迟低,适合实时场景。
- 避坑指南:我曾经遇到Hudi小文件问题,一个分区几千个小文件,查询慢得要死。后来加了
hoodie.clustering.inline=true才解决。
Iceberg适配要点:
- Iceberg的ACID事务能力是三个里面最完善的。它支持行级更新、删除和合并。
- 我建议用Iceberg 1.3+版本,因为1.3引入了
RowDelta操作,支持更细粒度的更新。 - Iceberg的Schema Evolution非常灵活。你可以随时加列、删列、改列类型,不会影响历史数据。
- 我个人习惯用Iceberg做数据湖仓,因为它对Trino和Flink的支持最好。
Delta Lake适配要点:
- Delta Lake的Time Travel功能很实用。你可以查询任意历史版本的数据。
- 我建议用Delta Lake 2.4+版本,因为2.4引入了
MERGE操作的性能优化。 - Delta Lake的Schema Enforcement很严格。写入数据如果不符合Schema,会直接报错。这其实是个好事,能避免脏数据入湖。
- 避坑指南:我曾经用Delta Lake做CDC入湖,结果因为Spark版本不兼容,Delta Lake的
MERGE操作一直报错。后来统一了Spark 3.3版本才解决。
3.4 链路架构总览
下面这张图是我总结的CDC入湖链路架构。Source端、中间件、Sink端三段清晰可见。你想想看,整个链路就像一条流水线,每一段都不能掉链子。
重要提醒:链路架构不是一成不变的。我建议每半年重新评估一次选型。因为数据库版本在升级,中间件在迭代,湖格式在演进。别一套方案用三年,到时候想改都改不动。
3.5 选型决策矩阵
最后,我整理了一个选型决策矩阵。你拿着这个表,对着自己的场景打勾,就知道该选什么了。
| 场景 | 推荐Source | 推荐中间件 | 推荐Sink | 理由 |
|---|---|---|---|---|
| 实时入湖、更新频繁 | MySQL 8.0 | Debezium | Hudi | Hudi的Upsert能力最强 |
| 多引擎查询、强一致性 | PostgreSQL 14+ | Debezium | Iceberg | Iceberg的ACID和Schema Evolution |
| Spark生态、Databricks | MySQL / Oracle | Canal / Debezium | Delta Lake | Delta Lake与Spark深度集成 |
| 离线全量同步 | 任意 | DataX | Hudi / Iceberg | DataX稳定可靠 |
| 低延迟、纯MySQL | MySQL 8.0 | Canal | Hudi | Canal延迟毫秒级 |
嗯,到这里,CDC入湖链路的Source端、中间件、Sink端选型就讲完了。记住一句话:没有最好的方案,只有最适合你的方案。选型之前,先搞清楚你的数据量、延迟要求、查询引擎和团队能力。这样才不会走弯路。