2. 实时入湖技术选型:Flink CDC、Kafka Connect、Spark Streaming对比,为什么Flink是首选?
做实时入湖,第一个要拍板的问题就是:选哪个引擎?
市面上喊得响的,无非就是 Flink CDC、Kafka Connect、Spark Streaming 这三家。我见过不少团队,上来就拍脑袋选了个“最熟悉的”,结果后面改架构改到吐血。今天咱们就把这三兄弟拉出来遛遛,看看它们各自的底牌。
2.1 三驾马车:各自的核心定位
先简单过一遍,它们分别是什么来头。
| 技术 | 核心定位 | 数据源 | 典型场景 |
|---|---|---|---|
| Flink CDC | 流式计算 + 变更数据捕获 | 数据库 Binlog、Kafka、Pulsar | 实时入湖、实时 ETL、数据同步 |
| Kafka Connect | Kafka 生态的连接器框架 | 数据库、文件系统、消息队列 | 数据管道、批量/准实时同步 |
| Spark Streaming | 微批次流处理引擎 | Kafka、文件、Socket | 准实时分析、批量 ETL、机器学习 |
说白了,Flink CDC 是“为实时而生”的,Kafka Connect 是“为管道而生”的,Spark Streaming 是“为批处理而生”的。定位不同,决定了它们在入湖场景里的表现天差地别。
2.2 核心对比:为什么 Flink 是首选?
咱们从四个最关键的维度来拆解:实时性、一致性、生态兼容性、运维复杂度。
2.2.1 实时性:毫秒级 vs 秒级 vs 分钟级
实时入湖,最核心的指标就是“延迟”。
- Flink CDC:基于 Debezium 引擎,直接读取 Binlog 的变更事件,毫秒级就能感知到数据变化。我做过一个压测,MySQL 写入一条记录,Flink 端 50ms 内就能在湖里看到。
- Kafka Connect:它本身是“拉取-推送”模式,依赖 Kafka 的轮询间隔。默认配置下,延迟通常在 1-5 秒。如果数据量大了,还可能因为 rebalance 导致延迟飙升。
- Spark Streaming:微批次模型,批次间隔最短也要 500ms,实际生产环境我见过设 5 秒、10 秒的。说白了,它就不是为“实时”设计的,而是“准实时”。
结论:如果你要的是“秒级以内”的入湖延迟,Flink CDC 是唯一选择。Kafka Connect 和 Spark Streaming 在延迟上根本不是一个量级。
2.2.2 一致性:Exactly-Once 的底气
入湖最怕什么?数据重复或者丢数据。尤其是金融、电商场景,一条记录对不上,排查起来要命。
- Flink CDC:原生支持 Exactly-Once 语义。它通过两阶段提交 + 动态分区写入,能保证每条变更记录只写一次到 Lakehouse。我在项目中遇到过,Flink 任务挂了重启,数据一条没多一条没少。
- Kafka Connect:默认是 At-Least-Once。如果任务挂了,重启后可能会重复消费。你需要自己写去重逻辑,或者依赖 Kafka 的幂等生产者,但那个只能保证单分区不重复,跨分区就难说了。
- Spark Streaming:通过 WAL(Write Ahead Log)也能做到 Exactly-Once,但实现起来比较绕。而且它的 checkpoint 机制在湖存储(如 HDFS、S3)上经常出问题,我见过好几次 checkpoint 写坏导致任务起不来的情况。
避坑指南:我曾经在一个项目中用 Kafka Connect 做入湖,结果因为网络抖动导致重复写入了 2 万条数据。排查了整整两天,最后只能写脚本去重。从那以后,凡是要求数据精确的场景,我坚决不用 Kafka Connect。
2.2.3 生态兼容性:Lakehouse 的“原住民”
Lakehouse 的核心是 Iceberg、Hudi、Delta Lake 这类表格式。引擎对它们的支持程度,直接决定了入湖的效率和复杂度。
| 特性 | Flink CDC | Kafka Connect | Spark Streaming |
|---|---|---|---|
| Iceberg 原生支持 | ✅ 原生 Flink Sink | ❌ 需自定义 Sink | ✅ 原生支持 |
| Hudi 原生支持 | ✅ 原生 Flink Sink | ❌ 需自定义 Sink | ✅ 原生支持 |
| Delta Lake 支持 | ✅ 通过 Flink Delta Connector | ❌ 社区支持弱 | ✅ 原生支持 |
| Schema Evolution | ✅ 自动演进 | ❌ 需手动处理 | ✅ 支持但需配置 |
| 分区写入 | ✅ 动态分区 + 自动提交 | ❌ 需自定义分区策略 | ✅ 支持但需手动管理 |
你想想看,Kafka Connect 连 Iceberg 的原生 Sink 都没有,你要自己写一个。写一个生产级的 Sink 少说也要两周,还要考虑容错、事务、性能……这成本太高了。
Spark Streaming 虽然支持,但它是微批次模型,写入 Lakehouse 时会产生大量小文件。我见过一个 Spark Streaming 入湖任务,跑了 3 小时,生成了 2 万多个小文件,把 Iceberg 的元数据服务都打崩了。
我的建议:Flink CDC + Iceberg/Hudi 是当前最成熟的组合。Flink 的 Streaming File Sink 天然支持小文件合并,你只需要配置好 compaction 策略,湖的写入性能会非常稳定。
2.2.4 运维复杂度:谁更省心?
做架构选型,不能只看功能,还得看“人”。
- Flink CDC:部署简单,一个 Flink 集群就能搞定。监控方面,Flink 的 Web UI 能看到每个算子的延迟、吞吐量、反压情况。出了问题,一眼就能定位。
- Kafka Connect:依赖 Kafka 集群 + Connect 集群。如果你有多个数据源,每个源都要配一个 Connector,配置项多到让人头大。而且 Kafka Connect 的监控很弱,出了问题经常要靠日志排查。
- Spark Streaming:需要 Spark 集群 + YARN/K8s。Spark 的作业管理比 Flink 重,而且微批次模型下,你很难精确知道“当前这一秒的数据处理完了没有”。
我记得有一次帮客户排查 Kafka Connect 的问题,发现是因为一个 Connector 的配置写错了,导致整个集群的 rebalance 持续了 20 分钟。换成 Flink CDC,这种问题根本不会出现——每个作业独立运行,互不干扰。
2.3 一张图看懂选型逻辑
下面这张图,是我自己总结的选型决策流程。你可以对照着看。
2.4 实战中的“隐形坑”
选型不是纸上谈兵,有些坑只有真正做过才知道。
- Kafka Connect 的 Schema 兼容性问题:如果你源表加了字段,Kafka Connect 默认会报错。你需要提前配好 Schema Registry 的兼容策略,否则入湖任务会直接挂掉。
- Spark Streaming 的小文件问题:前面提到了,微批次模型会产生大量小文件。我建议你配合 Iceberg 的
write.distribution-mode和write.target-file-size-bytes来控制,但说实话,效果还是不如 Flink 的 Streaming File Sink。 - Flink CDC 的 Binlog 压力:Flink CDC 读取 Binlog 时,如果并发太高,可能会给源库造成压力。我的经验是,一个 Flink CDC 任务不要同时监听超过 10 张表,否则 DBA 会来找你喝茶。
一个小技巧:如果你用 Flink CDC 入湖 Iceberg,记得开启 table.exec.sink.upsert-materialize 参数。它能帮你自动处理 CDC 中的 UPDATE 和 DELETE 事件,避免数据不一致。
2.5 总结:为什么 Flink 是首选?
说了这么多,其实就一句话:Flink CDC 在实时性、一致性、生态兼容性三个维度上,都明显优于另外两个选项。
Kafka Connect 适合“管道工”角色,做简单的数据搬运;Spark Streaming 适合“准实时”场景,比如小时级的报表。但如果你要做的是真正的实时入湖——秒级延迟、Exactly-Once、自动 Schema 演进——那 Flink CDC 就是目前最成熟、最省心的方案。