15.1 引擎选型指南

Kafka Streams 与 Flink 的适用场景深度对比:组织架构与运维成本差异、有状态轻量转换与复杂窗口/CEP 的分工策略、混合架构的典型拓扑(Kafka Streams 做清洗 + Flink 做计算),以及 Java 生态下的选型决策树。

选型不是二选一

eventd v3 的架构已经说明:Kafka Streams 和 Flink 可以共存,各自做擅长的事。

eventd v2 事件 → Kafka Topic "eventd-raw"
    → Kafka Streams(清洗:轻量有状态转换) ✓
        → Kafka Topic "eventd-cleaned"
            → Flink DataStream(聚合:复杂窗口/CEP) ✓
                → Redis → 面板

核心差异

维度Kafka StreamsFlink
部署模型嵌入应用(JAR)独立集群(Standalone/K8s)
运维复杂度低(Kafka 本身已存在)中(需要 JobManager/TaskManager)
状态存储本地 RocksDB + changelog TopicHashMap/RocksDB + Checkpoint
时间语义事件时间(默认取 record timestamp)+ 处理时间,无 WatermarkEvent Time + Watermark(乱序/空闲处理)+ 处理时间
窗口支持基础(Tumbling/Sliding/Session,带 grace period)丰富(+ 自定义 Trigger/Evictor、allowedLateness、侧输出迟到数据)
CEP无内置库(只能手写状态机 / Processor API)有(Flink CEP)
Exactly-OnceV2(Kafka 事务)Checkpoint 两阶段提交(仅对 Kafka 等支持 2PC 的 Sink 端到端成立)
SQL/Table API无有(Flink Table API/SQL)
扩展性水平(Consumer Group)水平(Slot 分配)
生态集成Kafka OnlyKafka/Redis/ES/JDBC 等

场景决策树

需要流处理?
    ├── 数据已经在 Kafka?
    │     ├── 只需要 filter/map/groupBy/窗口计数?
    │     │     └── ✅ Kafka Streams(轻量、低维护)
    │     ├── 需要对乱序做细粒度控制、allowedLateness、侧输出迟到数据?
    │     │     └── ✅ Flink(Streams 只有窗口级 grace period)
    │     ├── 需要 CEP 模式匹配?
    │     │     └── ✅ Flink CEP(Streams 需手写状态机)
    │     ├── 需要 SQL/声明式查询?
    │     │     └── ✅ Flink Table API/SQL
    │     └── 需要混合:清洗用 Streams,计算用 Flink?
    │           └── ✅ 两者都用(eventd v3 模式)
    └── 数据不在 Kafka?
          └── 先入 Kafka → 再选引擎

Kafka Streams 适用场景

场景理由
微服务事件处理每个服务自带 Streams 拓扑,无需外部集群
数据清洗/ETLfilter/map/简单的标准化
实时聚合(轻量)每用户计数、每分组求和
Kafka → Kafka 转换不引入新系统

典型业务:

// 清洗 + 简单聚合 + 写回 Kafka(JSON 字符串进出)
builder.stream("raw-events", Consumed.with(Serdes.String(), Serdes.String()))
    .filter((k, json) -> isValid(json))
    .mapValues(this::normalize)
    .groupByKey()
    .count(Materialized.as("count-store"))
    .toStream()
    .to("metrics", Produced.with(Serdes.String(), Serdes.Long()));
场景理由
实时风控CEP 模式匹配
复杂窗口滚动/滑动/会话 + 自定义 Trigger
实时 BIEvent Time 保证结果可复现
多流 JoinInterval Join、CoProcessFunction
机器学习推理窗口内特征聚合 → 模型输入

典型业务:

// CEP 风控:10 分钟内先大额、再连续两笔中等金额
Pattern<Event, ?> pattern = Pattern.<Event>begin("large")
    .where(e -> e.amount() > 10_000)
    .next("follow")
    .where(e -> e.amount() > 5_000)
    .times(2)
    .within(Duration.ofMinutes(10));

PatternStream<Event> matches = CEP.pattern(events.keyBy(Event::userId), pattern);

混合架构:最佳实践

eventd v3 的模式已经被验证可行:

Kafka Streams 做「边界网关」:
    → 数据进入系统时的第一道处理
    → 去重、标准化、简单的格式转换
    → 不需要精确时间语义,不需要 CEP

Flink 做「计算核心」:
    → 清洗后的数据做复杂计算
    → 窗口聚合、CEP、多流 Join
    → 需要精确时间语义和容错

好处:

  1. 各司其职:Streams 轻量,Flink 强大
  2. 故障隔离:Streams 故障不影响 Flink
  3. 演进灵活:可以单独升级任一引擎

团队能力考量

团队现状推荐起步
已有 Kafka,无流处理经验Kafka Streams
需要实时风控/BIFlink
已有 Spring 微服务Kafka Streams(同技术栈)
有大数据团队Flink(生态成熟)
两个团队都有混合(Streams + Flink)

成本考量

维度Kafka StreamsFlink
基础设施复用 Kafka需要额外集群
运维人力低中
学习曲线平缓(纯 Java)中等(需理解时间语义)
扩展成本同 Kafka需要规划 Slot/内存

小结

选择场景
只用 Kafka Streams轻量 ETL、微服务事件处理、已有 Kafka
只用 Flink复杂计算、CEP、实时 BI、需要 SQL
两者都用eventd v3 模式:清洗 + 深度计算

下一节 15.2 响应式流处理的演进趋势 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. 15.3 全书总结与学习路径回顾
  2. 15.2 响应式流处理的演进趋势
  3. 附录 B:Kafka Streams DSL 速查