2. 实时计算技术选型:Flink vs Spark Streaming vs Kafka Streams
做实时特征工程,第一关不是写代码,而是选引擎。
选错了,后面三个月都在填坑。选对了,事半功倍。今天我就把这三个主流引擎的底牌翻出来,结合我踩过的坑,给你一份能直接用的选型指南。
核心观点:没有最好的引擎,只有最合适的场景。选型的关键在于你的数据规模、延迟要求、以及团队的技术栈积累。
2.1 三驾马车:各自的血统与定位
先看一张总览图,把三者的定位搞清楚。
2.2 Apache Flink:实时特征工程的王者
Flink 是我个人在实时特征工程中的首选。为什么?因为它天生就是为「事件驱动」而生的。
你想想看,特征工程的核心是什么?是状态。用户的点击序列、滑动窗口内的统计值、实时的行为标签——这些都是状态。Flink 的状态管理是我用过的引擎里最成熟的。
我的经验:在做一个用户实时画像系统时,我们需要维护每个用户最近30分钟的点击序列。Flink 的 KeyedState 配合 RocksDB 状态后端,轻松支撑了百万级用户的实时状态更新。换做其他引擎,光状态管理就能让你掉一层皮。
Flink 的核心优势
- 真正的流处理:每条数据到达即处理,延迟在毫秒级。不是微批次,是真正的逐条处理。
- 精确一次语义:端到端的 exactly-once,对于金融风控等场景至关重要。
- 事件时间语义:支持乱序事件处理,watermark 机制成熟。我在处理 IoT 传感器数据时,设备上报时间经常乱序,Flink 的 watermark 帮我解决了大问题。
- 丰富的 Connector:Kafka、Pulsar、HDFS、Redis、Elasticsearch……几乎你能想到的数据源都有现成的连接器。
Flink 的短板
- 学习曲线陡峭:概念多(Checkpoint、Savepoint、State Backend、Slot……),新手容易懵。
- 运维成本高:需要独立集群,JobManager 挂了要恢复,资源调优是个技术活。
- 批处理能力弱于 Spark:虽然 Flink 也在推批流一体,但批处理场景还是 Spark 更成熟。
2.3 Spark Streaming:批流一体的老牌劲旅
Spark Streaming 的核心思想是「微批次」。把实时数据流切成一个个小批次,然后用 Spark 的批处理引擎去算。说白了,就是用批处理的方式模拟实时。
我记得在 2018 年,我接手了一个实时 ETL 项目。团队里全是 Spark 工程师,没人懂 Flink。当时我们硬着头皮用 Spark Streaming 做了实时特征计算。结果呢?延迟在 5-10 秒,勉强能用,但状态管理是真的痛苦。
避坑指南:我曾经在一个项目中,用 Spark Streaming 做滑动窗口统计。窗口大小 5 分钟,滑动步长 10 秒。结果每个窗口都要重新计算,状态膨胀得厉害,GC 频繁。后来改用 Flink 的滑动窗口,性能提升了 3 倍。所以,如果你的场景涉及大量状态操作,慎用 Spark Streaming。
Spark Streaming 的核心优势
- 与 Spark 生态无缝集成:如果你已经在用 Spark 做批处理,Spark Streaming 的学习成本几乎为零。
- 强大的 SQL 支持:Structured Streaming 让用户可以用 SQL 写流处理逻辑,门槛低。
- 社区活跃:文档丰富,遇到问题容易找到解决方案。
Spark Streaming 的短板
- 微批次架构的固有限制:延迟在秒级,无法做到毫秒级响应。
- 状态管理较弱:虽然 Structured Streaming 改进了状态管理,但和 Flink 比还是有差距。
- 资源消耗大:每个微批次都要调度资源,小批次场景下资源利用率不高。
2.4 Kafka Streams:轻量级的流处理库
Kafka Streams 不是框架,是一个 Java 库。它不需要独立的集群,直接嵌入你的应用里。你想想看,这意味着什么?部署简单,运维成本低。
我在做一个日志实时聚合的小项目时,就用过 Kafka Streams。需求很简单:统计每台机器的 QPS,输出到另一个 Topic。整个代码不到 100 行,打包成 jar 直接跑,连集群都不用搭。
适用场景:Kafka Streams 最适合「轻量级」的流处理任务。比如简单的过滤、转换、聚合。如果你的业务逻辑复杂,需要多流 Join、复杂窗口、外部状态查询,那还是上 Flink 吧。
Kafka Streams 的核心优势
- 无独立集群:作为库嵌入应用,部署简单,运维成本低。
- 与 Kafka 深度集成:利用 Kafka 的分区机制实现并行处理,天然支持 exactly-once。
- 轻量级:适合微服务架构中的流处理需求。
Kafka Streams 的短板
- 功能有限:复杂的状态操作、多流 Join、事件时间处理不如 Flink 强大。
- 仅支持 Java:虽然也有 Kafka Streams DSL,但本质上还是 Java 生态。
- 调试困难:作为库嵌入应用,出现问题难以隔离排查。
2.5 选型对比:一张表说清楚
| 对比维度 | Apache Flink | Spark Streaming | Kafka Streams |
|---|---|---|---|
| 架构模式 | 事件驱动(逐条处理) | 微批次(Mini-Batch) | 事件驱动(库模式) |
| 延迟 | 毫秒级 | 秒级 | 毫秒级 |
| 状态管理 | 强大(KeyedState、OperatorState) | 中等(StateStore) | 基础(StateStore) |
| 精确一次语义 | 端到端支持 | 支持(需配置) | 支持(依赖Kafka) |
| 事件时间 | 原生支持,Watermark成熟 | 支持(Structured Streaming) | 支持(有限) |
| 部署方式 | 独立集群 | 独立集群 | 嵌入应用(无集群) |
| 学习曲线 | 陡峭 | 中等(有Spark基础) | 平缓(Java开发者友好) |
| 适用场景 | 复杂实时特征、状态密集型作业 | 准实时ETL、批流一体 | 轻量级流处理、Kafka原生生态 |
2.6 我的选型建议
说了这么多,到底怎么选?我给出三个原则:
- 看延迟要求:毫秒级响应选 Flink 或 Kafka Streams;秒级响应 Spark Streaming 也能接受。
- 看状态复杂度:复杂状态操作(多流 Join、长窗口、状态回溯)无脑选 Flink。
- 看团队技术栈:团队全是 Spark 工程师,且延迟要求不高,Spark Streaming 是务实之选。团队 Java 为主,任务简单,Kafka Streams 性价比最高。
我的最终建议:对于实时特征工程这个领域,我个人强烈推荐 Flink。特征工程天然就是「状态密集型」的,Flink 的状态管理、事件时间语义、精确一次保证,几乎是为这个场景量身定做的。如果你正在从零搭建实时特征平台,别犹豫,选 Flink。
当然,实际生产中三者并不互斥。我见过很多团队用 Flink 做核心特征计算,用 Kafka Streams 做简单的数据预处理,用 Spark Streaming 做离线批处理的补充。工具是死的,人是活的。理解了各自的优劣,你就能在合适的场景用合适的工具。