3. 核心技术选型:Flink vs Spark Streaming、Kafka vs Pulsar、Hudi vs Iceberg vs Delta Lake

做流批一体架构,最头疼的就是选型。我见过不少团队,一上来就追新,结果被坑得够呛。这一章,我把几个核心组件的选型思路掰开揉碎讲清楚。

说白了,选型没有银弹。你得根据自己团队的技术栈、数据规模、实时性要求来权衡。我习惯把选型分成三层来看:计算引擎、消息队列、存储层。咱们一层一层聊。

核心观点: 流批一体不是技术竞赛,是工程取舍。选型时优先考虑团队熟悉度,其次才是技术先进性。

3.1 计算引擎:Flink vs Spark Streaming

这两个是绕不开的对手。我两个都用过,踩过不少坑。先看一张对比图,心里有个底。

计算引擎选型对比 Apache Flink • 真正的流式计算引擎 • 事件时间语义,精确一次 • 状态管理强大,Checkpoint 成熟 • 流批一体原生支持 • 适合:实时ETL、风控、监控 Spark Streaming • 微批次架构(本质是批) • Structured Streaming 改进不少 • 生态丰富,SQL 支持好 • 批处理性能优于 Flink • 适合:离线+准实时、数据湖 选型建议 • 实时性要求高(秒级延迟)→ Flink • 批处理为主,偶尔做流 → Spark 我的经验 • API 数据服务场景:Flink 更合适,因为延迟可控 • 如果团队 Spark 经验丰富,用 Structured Streaming 也能凑合

3.1.1 Flink 的优势

Flink 的设计哲学就是「流是一切」。它把批当成有界流来处理。这个思路,在做 API 数据服务时特别有用。

我记得有个项目,需要实时聚合用户行为数据,然后通过 API 对外暴露。用 Flink 的 DataStream API,配合 Event Time 和 Watermark,延迟控制在 2 秒以内。如果用 Spark Streaming,微批次间隔至少 5 秒,用户体验就差一截。

小技巧: Flink 的 Checkpoint 机制是它的杀手锏。我习惯把 Checkpoint 间隔设为 30 秒,状态后端用 RocksDB,这样即使任务挂了,恢复也很快。

3.1.2 Spark Streaming 的适用场景

别把 Spark Streaming 一棍子打死。如果你的场景是「准实时」——比如延迟容忍度在 1 分钟以上,那 Spark 的生态优势就体现出来了。

我曾经帮一个客户做数据湖项目,他们用 Spark 做批处理,偶尔需要跑一些流任务。这种情况下,统一用 Spark 比引入 Flink 更划算。毕竟团队不用学两套东西。

注意: Spark Streaming 的微批次架构,在处理乱序数据时比较吃力。如果你对数据准确性要求极高,比如金融场景,建议优先考虑 Flink。

3.2 消息队列:Kafka vs Pulsar

消息队列是流批一体的「血管」。数据从源头到计算引擎,全靠它。我最早用 Kafka,后来接触 Pulsar,各有千秋。

消息队列选型对比 Apache Kafka • 吞吐量极高,生态成熟 • 分区顺序保证,Exactly-Once • 存储与计算耦合,扩缩容麻烦 • 适合:大规模日志收集、事件流 Apache Pulsar • 存算分离,弹性伸缩 • 原生支持多租户、分层存储 • 延迟更低,但生态不如 Kafka • 适合:云原生、多租户场景 选型建议 • 团队熟悉 Kafka,且场景固定 → 继续用 Kafka • 需要弹性伸缩、多租户隔离 → Pulsar 更香 • API 数据服务场景:两者都行,看团队技术栈

3.2.1 Kafka 的统治地位

Kafka 的生态太强了。Flink、Spark、Hudi、Iceberg 全都原生支持 Kafka。你几乎找不到一个不支持 Kafka 的流处理框架。

我有个项目,每天处理 10 亿条消息,Kafka 集群 30 个节点,稳如老狗。但有个痛点:扩缩容太麻烦。每次加节点,要重新平衡分区,搞不好还会影响线上服务。

避坑指南: 我曾经因为 Kafka 分区数设置不合理,导致数据倾斜。后来总结了一个经验:分区数 = 消费者线程数 × 2,这样既能保证并行度,又有余量。

3.2.2 Pulsar 的后发优势

Pulsar 的存算分离架构,天生适合云原生。它的 BookKeeper 做存储,Broker 做计算,扩缩容跟玩似的。

我记得有个客户,业务增长快,Kafka 集群扩了又扩,每次都要停机。后来换成 Pulsar,加节点就像加 Pod 一样简单。而且 Pulsar 的分层存储,能把冷数据自动迁移到 S3,省钱又省心。

注意: Pulsar 的客户端生态不如 Kafka 丰富。如果你要用一些偏门的 Connector,可能会遇到坑。建议先做 PoC 验证。

3.3 存储层:Hudi vs Iceberg vs Delta Lake

存储层是流批一体的「地基」。这三个都是表格式(Table Format),不是存储引擎。它们解决的是同一个问题:怎么让数据湖支持 ACID、时间旅行、增量查询。

存储层选型对比 Apache Hudi • 增量处理能力强 • 支持 Upsert/Delete • 索引机制成熟 • 适合:CDC、增量ETL • 与 Flink 集成好 Apache Iceberg • 表格式规范,开放 • 快照隔离,时间旅行 • 分区演进,隐藏分区 • 适合:数据湖、查询场景 • 与 Spark 集成好 Delta Lake • Databricks 出品 • ACID 事务,Schema 强制 • 与 Spark 深度绑定 • 适合:Databricks 生态 • 性能优化好 选型建议 • 用 Flink 做流处理 → Hudi(增量能力强) • 用 Spark 做批处理,需要开放格式 → Iceberg • 团队在 Databricks 生态内 → Delta Lake 我的经验 • API 数据服务场景,我推荐 Hudi + Flink 组合,增量查询性能好 • 如果团队 Spark 为主,Iceberg 更合适,社区活跃,兼容性好

3.3.1 Hudi:增量处理的王者

Hudi 的核心理念是「增量处理」。它支持 Copy-on-Write 和 Merge-on-Read 两种存储类型。前者写放大,后者读放大。

我有个 API 数据服务项目,数据源是 MySQL 的 CDC 流。用 Hudi 的 Merge-on-Read 模式,配合 Flink,实现了秒级的数据同步。API 查询时,直接读 Hudi 的 Parquet 文件,性能杠杠的。

小技巧: Hudi 的索引是关键。我习惯用 Bucket 索引,配合 Flink 的 Keyed State,避免数据倾斜。记得把索引并行度调大一点。

3.3.2 Iceberg:开放的表格式

Iceberg 的设计更「学术派」。它把表格式定义得非常清晰,快照隔离、分区演进、隐藏分区,这些特性让数据湖管理变得优雅。

我记得有个数据湖项目,数据量几百 TB,查询模式多变。用 Iceberg 的分区演进功能,随时调整分区策略,不用重写历史数据。这一点,Hudi 和 Delta Lake 都做不到。

注意: Iceberg 的增量处理能力不如 Hudi。如果你需要频繁的 Upsert 和 Delete,Iceberg 的性能会下降。建议评估场景后再选。

3.3.3 Delta Lake:Databricks 的生态利器

Delta Lake 是 Databricks 的亲儿子。如果你在用 Databricks 平台,那 Delta Lake 是首选。它的 ACID 事务、Schema 强制、性能优化,都是顶级的。

但有个问题:Delta Lake 跟 Spark 绑定太深。如果你用 Flink 做流处理,集成 Delta Lake 会比较麻烦。我见过有人硬搞,结果踩了一堆坑。

总结: 选型没有标准答案。我的建议是:先确定计算引擎,再选消息队列,最后定存储层。三者要匹配,才能发挥最大效能。

3.4 选型决策矩阵

最后,我整理了一个决策矩阵,方便你快速对比。这个矩阵是我多年经验总结的,你可以直接拿来用。

场景 计算引擎 消息队列 存储层
实时 API 数据服务 Flink Kafka / Pulsar Hudi
准实时数据湖 Spark Kafka Iceberg
CDC 增量同步 Flink Kafka Hudi
Databricks 生态 Spark Kafka Delta Lake
云原生弹性场景 Flink Pulsar Iceberg

嗯,这一章的内容就到这里。选型是个动态过程,别指望一次选对。我建议你先做个小规模 PoC,跑通核心链路,再逐步优化。毕竟,实践出真知。