算子链
Flink 的算子链(Operator Chaining)是一种重要的优化技术,通过将多个算子链接成一个任务(Task),可以减少线程间通信、序列化 / 反序列化开销,从而显著提升作业性能。以下从原理到实践详细介绍算子链优化:
一、算子链的基本原理
1. 什么是算子链?
- Flink 默认会将多个算子(如 map、filter、keyBy 等)链接成一个 Task,形成一个算子链(也称为任务链)。
- 链内算子在同一个线程中执行,数据通过内存传递,无需序列化和网络传输。
2. 为什么需要算子链?
- 减少开销:避免线程切换、序列化 / 反序列化和网络传输。
- 降低延迟:数据在内存中直接传递,无需跨节点传输。
- 简化并行执行:减少 Task 数量,降低资源管理复杂度。
二、算子链的形成条件
Flink 会自动将满足以下条件的算子链接在一起:
- 上下游算子并行度相同
- 数据传输方式为 Forward(非 KeyBy、Shuffle 等重分区操作)
- 算子位于同一 Slot 共享组(默认所有算子在
default
组) - 没有禁用算子链(未调用
disableChaining()
)
示例:默认算子链
DataStream<String> stream = env.readTextFile("input.txt");
// map和filter会被链接成一个Task
DataStream<String> filtered = stream
.map(line -> line.toUpperCase())
.filter(line -> line.contains("ERROR"));
// keyBy会中断链,window和sum形成新链
KeyedStream<String, String> keyed = filtered.keyBy(line -> line.split(",")[0]);
DataStream<String> result = keyed
.window(TumblingEventTimeWindows.of(Time.seconds(10)))
.sum(1);
三、手动控制算子链
Flink 提供了三种 API 来手动控制算子链的形成: