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端三段清晰可见。你想想看,整个链路就像一条流水线,每一段都不能掉链子。

CDC入湖链路架构总览 CDC入湖链路架构总览 Source端 MySQL Binlog Row格式 Oracle Redo Log / LogMiner PostgreSQL WAL Logical Replication 其他数据源 MongoDB / SQL Server 中间件 Debezium Kafka Connect Connector Canal MySQL Slave协议 DataX 离线批量拉取 其他中间件 Maxwell / StreamSets Sink端 Apache Hudi 增量查询 / Upsert Apache Iceberg ACID事务 / Schema Evolution Delta Lake Time Travel / Schema Enforcement 其他湖格式 Paimon / Hive 说明: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端选型就讲完了。记住一句话:没有最好的方案,只有最适合你的方案。选型之前,先搞清楚你的数据量、延迟要求、查询引擎和团队能力。这样才不会走弯路。