Kafka Streams vs Flink:别再纠结了,选错不是技术问题,是场景没想清楚
我是 Echo_Wish。
说实话,这几年我被问得最多的一个问题之一就是:
👉 “哥,Kafka Streams 和 Flink 到底该选哪个?”
每次听到这个问题,我心里都会默默回一句:
这俩不是对手,是性格完全不一样的两个人。
你非要让一个居家暖男去打职业拳击,或者让一个综合格斗选手天天在厨房切菜,那不出事才怪。
今天这篇文章,我不想做那种“参数对比表 + 官方文档复读机”,而是从真实工程视角出发,聊聊它们各自擅长什么、坑在哪、什么时候用会很爽,什么时候用会后悔。
一、先一句话说结论(给忙人看的)
Kafka Streams:
- 小而美
- 写在业务代码里
- 低运维成本
- 非常适合“流式逻辑就是业务逻辑”的场景
Flink:
- 重装上阵
- 专业流计算引擎
- 状态、时间、复杂计算无敌
- 适合“数据处理本身就是核心系统”的场景
如果你现在还没概念,别急,下面慢慢拆。
二、Kafka Streams:写业务代码,顺手把流处理干了
1️⃣ Kafka Streams 的本质是什么?
一句人话版解释:
Kafka Streams = 写 Java 程序时,顺便把 Kafka 当数据库用。
它不是一个“平台”,也不是一个“集群产品”,而是一个 Java Library。
没有 JobManager
没有 TaskManager
没有 Yarn / K8s 强依赖
你写个 main 方法,它就能跑。
2️⃣ 一个最典型的 Kafka Streams 代码长这样
Properties props = new Properties();
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-app");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> source = builder.stream("input-topic");
source
.flatMapValues(value -> Arrays.asList(value.toLowerCase().split(" ")))
.groupBy((key, word) -> word)
.count()
.toStream()
.to("output-topic");
KafkaStreams streams = new KafkaStreams(builder.build(), props);
streams.start();
你看这代码,有没有一种感觉:
“这不就是我平时写业务逻辑吗?”
没错,这就是 Kafka Streams 最大的魅力:
- 没有“作业提交”的概念
- 没有“平台依赖感”
- 就是代码 = 逻辑 = 服务
3️⃣ Kafka Streams 适合什么场景?
我给你几个非常真实的使用场景:
✅ 场景一:事件驱动的业务系统
比如:
- 订单状态流转
- 用户行为实时聚合
- 风控规则实时判断
这些逻辑往往:
- 强业务耦合
- 逻辑复杂但数据规模不算天文
- 更关注“稳定 + 可维护”
Kafka Streams 非常合适。
✅ 场景二:你不想养一个“流计算平台”
说句大实话:
很多公司根本不需要 Flink 集群。
你就三五个流任务,却要:
- 运维一套 Flink
- 管状态
- 管 checkpoint
- 管升级
Kafka Streams 一个 Jar 包解决。
4️⃣ Kafka Streams 的短板(说点实在的)
它也不是万能的,我踩过坑:
- ❌ 事件时间 & Watermark 能力弱
- ❌ 复杂 Window / Join 写起来很别扭
- ❌ 状态规模一大,RocksDB 调优能把你搞崩
一句话总结:
Kafka Streams:能用,但别指望它像 Flink 那样优雅地“玩时间”。
三、Flink:这是专业选手,不是来陪你写业务的
1️⃣ Flink 是什么?
说句不太严谨但很形象的话:
Flink = 实时版的 Spark + 状态机 + 时间引擎。
它天生就是为 “复杂、长期运行、状态巨大” 的流计算而生的。
2️⃣ 一个 Flink 流处理代码,通常是这样的
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> source = env.fromSource(
KafkaSource.<String>builder()
.setBootstrapServers("localhost:9092")
.setTopics("input-topic")
.setValueOnlyDeserializer(new SimpleStringSchema())
.build(),
WatermarkStrategy.noWatermarks(),
"Kafka Source"
);
source
.flatMap(new Tokenizer())
.keyBy(value -> value.word)
.window(TumblingEventTimeWindows.of(Time.minutes(1)))
.sum("count")
.print();
env.execute("Flink WordCount");
你会明显感觉到:
- 有“作业”的概念
- 有“执行环境”的概念
- 有“时间语义”的概念
这是数据系统的语言,不是业务系统的语言。
3️⃣ Flink 真正厉害的地方
我只说三个点,都是 Kafka Streams 很难打的:
🔥 1. 事件时间处理
- Watermark
- Late data
- 精准窗口
如果你关心 “业务时间而不是处理时间”,Flink 几乎是唯一答案。
🔥 2. 超大状态
- 百 GB / TB 级状态
- 后端状态抽象
- 增量 Checkpoint
Kafka Streams 能跑,但你会越来越不安;Flink 是为这个而生的。
🔥 3. SQL + CDC + 湖仓一体
今天的 Flink,已经不是“写代码”的工具了:
- Flink SQL
- Flink CDC
- 实时写 Iceberg / Hudi
它已经站在 实时数仓 & 实时数据平台 这个高度了。
4️⃣ Flink 的代价(别装没看见)
实话实说:
- ❌ 学习曲线陡
- ❌ 运维复杂
- ❌ 小需求用它,有点“杀鸡用牛刀”
很多团队不是技术不行,是没这个规模,硬上 Flink 反而拖慢交付。
四、我给你的“接地气选型口诀”
一句话记住:
👉 选 Kafka Streams,如果:
- 流处理 = 业务逻辑的一部分
- 你想要 低运维 + 快交付
- Kafka 是你系统的绝对核心
👉 选 Flink,如果:
- 流处理本身就是核心系统
- 对时间、状态、正确性极度敏感
- 你在做 实时数仓 / 实时风控 / 实时指标平台
五、说点我自己的感受(不是文档能告诉你的)
这些年下来,我越来越觉得:
技术选型的本质不是“哪个更牛”,而是“哪个更像你现在的团队”。
- 人少、节奏快、业务压人 👉 Kafka Streams
- 数据规模大、系统生命周期长 👉 Flink
别为了“看起来高级”选 Flink,
也别因为“轻量”硬把 Kafka Streams 用成流计算平台。
六、最后一句话送你
Kafka Streams 是把“流”拉进业务世界;
Flink 是把“业务”推向数据世界。
想清楚你站在哪一边,答案自然就出来了。