Flink 工作流程剖析
Flink 工作流程剖析
Apache Flink 是一个分布式流计算框架,支持高吞吐、低延迟、状态管理,并具备批流一体的特性。
1. Flink 任务执行流程
Flink 作业从代码编写到实际运行的完整流程如下:
- 用户编写 Flink 作业代码
- Flink 编译作业并生成 JobGraph
- JobManager 解析 JobGraph,生成 ExecutionGraph
- TaskManager 分配 Slot 并执行任务
- 数据流转,触发 Checkpoint 机制,维护状态
- 作业完成或失败后进行资源释放
下图展示了 Flink 执行流程:
┌───────────────────────────────────────────────┐
│ 用户提交 Flink 作业(main) │
└───────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ Client 解析代码,生成 JobGraph │
└───────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ JobManager 接收 JobGraph,转换成 ExecutionGraph │
└───────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ JobManager 请求 TaskManager 分配 TaskSlot │
└───────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ TaskManager 运行 Task 处理数据 │
└───────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ 触发 Checkpoint 进行状态快照存储 │
└───────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────┐
│ 作业完成(成功 / 失败),释放资源,记录结果 │
└───────────────────────────────────────────────┘
2. 详细执行流程剖析
2.1 用户提交作业
用户通过 DataStream API / Table API / SQL 编写 Flink 任务,并调用 env.execute("Job Name")
提交任务。
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> stream = env.fromElements("Hello", "Flink");
stream.print();
env.execute("Flink Job");
此时,Flink Client 负责:
- 解析用户代码,构造
JobGraph
- 提交
JobGraph
到 JobManager 进行调度
2.2 JobGraph 解析
JobGraph 是 Flink 作业的逻辑执行计划,由 StreamGraph
转换而来,包含:
- Vertices(节点):代表算子(Source、Map、Reduce、Sink)
- Edges(边):表示数据流的依赖关系
Source → Map → KeyBy → Window → Sink
示例:
env.fromElements(1, 2, 3)
.map(value -> value * 2)
.print();
对应的 JobGraph
:
(Source) → (Map) → (Sink)
2.3 ExecutionGraph 生成
JobManager 接收 JobGraph
,转换成 ExecutionGraph,它是 Flink 内部用于调度执行的 物理执行计划。
ExecutionGraph 由多个 ExecutionVertex 组成,每个 ExecutionVertex 对应 Task
的一个并行子任务。
示例: 假设 JobGraph
任务有 Map → KeyBy → Reduce
,如果 Map
并行度=2,Reduce
并行度=1:
[ExecutionGraph]
├── (Task1-1, Task1-2) [Map]
└── (Task2-1) [Reduce]
2.4 任务调度
TaskManager(TM) 是 Flink 的计算节点,JobManager(JM) 负责为 ExecutionGraph 任务分配 TaskSlot 进行调度:
- JobManager 请求 TaskManager 提供资源
- TaskManager 返回可用 Slot
- JobManager 将 ExecutionVertex 映射到 TaskSlot
- 任务启动并运行
Flink 使用 Slot Sharing(槽共享),多个算子可以共享一个 TaskSlot,提高资源利用率。
2.5 Task 执行 & 数据流
Task 是 Flink 执行单元,Task 运行后:
- Source 读取数据
- 算子(Operators)执行计算
- 通过 Network Shuffle 传输数据
- Sink 输出数据
数据流可以是:
- 批处理(Batch):有界数据,数据处理完后作业终止
- 流处理(Streaming):无界数据,作业持续运行
示例:
DataStream<String> stream = env.fromElements("A", "B", "C")
.map(value -> value.toLowerCase());
此时,Flink 任务流:
Source(A, B, C) → Map(a, b, c) → Sink
2.6 Checkpoint & State 维护
Flink 采用 异步 Checkpoint 机制保证数据一致性:
- Source 生成 Barrier(屏障)
- Barrier 随数据流传播
- 各 Task 保存状态到 StateBackend
- 当所有 Task 确认 Checkpoint 完成,作业状态存入持久化存储(如 HDFS、RocksDB)
示例:
env.enableCheckpointing(5000); // 5 秒触发一次 Checkpoint
2.7 作业完成 / 失败
- 正常完成:Flink 释放资源,关闭作业
- 失败重启:
- 失败恢复(RestartStrategy):
- 固定间隔重启
- 失败次数限制
- 无限重启
- 状态恢复(StateBackend):
- 通过 Checkpoint 进行状态恢复
- 失败恢复(RestartStrategy):
示例:
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3, Time.seconds(10)));
3. 总结
Flink 任务执行的完整流程:
- 用户代码提交
- Client 生成 JobGraph
- JobManager 解析 JobGraph,构建 ExecutionGraph
- TaskManager 分配 Slot 并启动任务
- 数据流动 & 状态管理
- Checkpoint 保障容错
- 作业完成 / 失败重启
License:
CC BY 4.0