Flink 运行时架构 & 完整任务提交流程
本文详细解析了Apache Flink分布式流处理引擎的运行时架构和任务提交流程。Flink采用分层架构,包括客户端层(负责作业提交)、主节点JobManager(负责作业调度和管理)、资源管理器(负责资源分配)、任务执行节点TaskManager(负责实际计算)以及外部服务(提供高可用和状态存储支持)。任务提交流程包含8个关键步骤:从用户提交作业开始,经过StreamGraph生成、JobGra
Flink 运行时架构 & 完整任务提交流程
深入理解 Apache Flink 分布式流处理引擎的核心设计
一、整体架构分层
Flink 运行时由 5 层构成,从上到下依次为:
┌─────────────────────────────────────────────────────┐
│ Client Layer(客户端层) │
│ Flink CLI │ REST API │ Web UI │ DataStream API │
└───────────────────────┬─────────────────────────────┘
│ 提交 JobGraph
┌───────────────────────▼─────────────────────────────┐
│ Master Node — JobManager(主节点) │
│ Dispatcher │ JobMaster │ Scheduler │ BlobServer │
│ CheckpointCoordinator │
└──────────┬────────────────────────┬─────────────────┘
│ 申请 Slot │ 注册/心跳
┌──────────▼──────────┐ ┌────────▼─────────────────┐
│ ResourceManager │ │ TaskManager × N │
│ SlotManager │ │ Task Slot × N │
│ YARN/K8s Deployer │ │ Operator Chain │
└─────────────────────┘ │ Network Stack │
└───────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ External Services(外部存储 & 协调) │
│ ZooKeeper/K8s(HA) │ RocksDB/Heap │ HDFS/S3 │
└─────────────────────────────────────────────────────┘
二、核心组件详解

💻 Client(客户端)
Client 是用户与 Flink 集群交互的入口,本身不参与实际计算,只负责作业的编译与提交。
- 解析用户的 DataStream / Table API 代码,生成 StreamGraph
- 将 StreamGraph 优化为 JobGraph(合并可 Chain 的算子)
- 将 JobGraph 及 Jar 包序列化后提交给 Dispatcher
- 支持通过 CLI / REST API / Web UI 三种方式操作
🎯 JobManager(作业管理节点)
JobManager 是 Flink 集群的大脑,是 Master 节点,包含多个核心子组件:
| 子组件 | 职责 |
|---|---|
| Dispatcher | 接收 Job 提交,持久化 JobGraph,为每个 Job 孵化独立的 JobMaster |
| JobMaster | 负责单个作业的全生命周期,将 JobGraph 展开为 ExecutionGraph |
| Scheduler | 决定 Task 的调度策略与执行顺序 |
| CheckpointCoordinator | 周期性触发分布式快照,协调所有 TM 完成 Checkpoint |
| BlobServer | 负责 Jar 包、配置等文件的分发与存储 |
⚙️ ResourceManager(资源管理器)
ResourceManager 是 Flink 集群的资源调度中心,屏蔽底层资源系统差异(YARN / K8s / Standalone 三种模式统一接口)。
- 管理所有 TaskManager 及其 Task Slot 的注册与状态
- 接收 JobMaster 的 Slot 请求,将合适的 Slot 分配给对应 Job
- 在 YARN/K8s 模式下,负责向外部资源系统申请启动新的 TaskManager
- 监控 TaskManager 心跳,处理 TM 的注册 / 注销 / 超时
🔧 TaskManager(任务执行节点)
TaskManager 是 Flink 的 Worker 节点,包含若干 Task Slot,所有实际计算在此发生。
| 子模块 | 说明 |
|---|---|
| Task Slot | 资源隔离单元,每个 Slot 持有固定比例的 JVM 内存 |
| Operator Chain | 将多个算子串联在同一线程执行,减少序列化 / 网络开销 |
| Network Stack | 管理 Task 间数据传输(基于 Netty + Credit-based 流控) |
| Memory Manager | 管理 Managed Memory(用于排序、哈希、State 等) |
TaskManager 定期向 JobManager 上报心跳和 Task 状态。
🛡️ 高可用 & Checkpoint
| 机制 | 说明 |
|---|---|
| ZooKeeper/K8s HA | JobManager Leader 选举,避免单点故障 |
| Checkpoint | 基于 Chandy-Lamport 算法的分布式快照,定期持久化全局状态 |
| Savepoint | 用户手动触发的 Checkpoint,支持作业升级 / 迁移 |
| State Backend | HashMapStateBackend(内存)或 RocksDBStateBackend(磁盘) |
三、完整任务提交流程(8 步)

User
│
│ 1. 编写代码,调用 env.execute(),生成 StreamGraph
▼
Client
│
│ 2. StreamGraph → JobGraph(算子链合并),HTTP 提交
▼
Dispatcher
│
│ 3. 持久化 JobGraph,创建 JobMaster
▼
JobMaster
│
│ 4. JobGraph → ExecutionGraph(按并行度展开),申请 Slot
▼
ResourceManager
│
├─── 有空闲 Slot ──────────────────────────────┐
│ │
│ 5. 无空闲 Slot,向 YARN/K8s 申请新 TM │
▼ │
TaskManager(新启动) │
│ │
│ 6. 向 RM 注册,RM 将 Slot 信息通知 JobMaster │
└───────────────────────────────────────────────┘
│
│ JobMaster 确认 Slot 分配(RPC)
▼
TaskManager
│
│ 7. JobMaster 下发 Task,TM 在 Slot 中启动 OperatorChain
▼
Task 开始执行
│
│ 8. 持续运行:心跳监控 + 定期 Checkpoint + 故障恢复
▼
作业完成 → 释放 Slot
各步骤说明
Step 1 — 用户提交(User → Client)
用户通过 DataStream API / Table API / SQL 编写作业,调用 env.execute() 触发提交。Client 在本地解析算子 DAG,构建 StreamGraph(纯逻辑拓扑,包含所有算子节点和边)。
Step 2 — 生成 JobGraph(Client → Dispatcher)
Client 将 StreamGraph 进行算子链合并优化,生成 JobGraph(减少不必要的序列化/反序列化)。随后将 JobGraph + 用户 Jar 包,通过 HTTP REST 接口发送至 Dispatcher。
Step 3 — Dispatcher 持久化 & 创建 JobMaster
Dispatcher 接收 JobGraph 后,将其持久化到 HA 存储(ZooKeeper/K8s)以支持故障恢复,然后为该作业创建专属的 JobMaster 实例,将作业完整管理权移交给 JobMaster。
Step 4 — 生成 ExecutionGraph & 申请资源(JobMaster → ResourceManager)
JobMaster 将 JobGraph 按并行度展开,生成 ExecutionGraph(每个算子拆分为多个 ExecutionVertex)。随后向 ResourceManager 发送 Slot 请求,申请执行任务所需的计算资源。
Step 5 — ResourceManager 分配 / 启动 TaskManager
- 有空闲 Slot:直接将 Slot offer 给 JobMaster
- 无空闲 Slot:向外部系统(YARN/K8s)申请启动新的 TaskManager 进程,等待 TM 注册后再分配 Slot
Step 6 — TaskManager 注册 & Slot 分配确认
新启动的 TaskManager 向 ResourceManager 完成注册,汇报其 Slot 数量。ResourceManager 将 Slot 信息转发给 JobMaster,JobMaster 通过 RPC 直接与 TaskManager 通信,确认 Slot 分配。
Step 7 — Task 部署 & 启动执行(JobMaster → TaskManager)
JobMaster 将 ExecutionGraph 中的每个 Task(含算子代码、状态描述、网络连接信息)序列化,通过 RPC 发送给对应的 TaskManager。TaskManager 将 Task 提交到对应 Slot 线程开始执行,同一 Slot 内的多个算子组成 Operator Chain,在同一线程中运行。
Step 8 — 作业运行 & 持续监控
- TaskManager 定期向 JobMaster 发送心跳 + Task 状态
- CheckpointCoordinator 周期性向所有 Source Task 注入 Barrier,触发分布式 Checkpoint
- 发生 Task 失败时,JobMaster 根据重启策略决定是否重启,并从最近的 Checkpoint 恢复状态
- 作业完成后,JobMaster 通知 ResourceManager 释放所有 Slot,TM 资源归还
💡 Session vs Per-Job vs Application 模式
- Session 模式:Dispatcher 和 ResourceManager 是预先启动的共享集群,多个 Job 共用
- Per-Job 模式:每个作业独占一套 JobManager,资源隔离更彻底(已废弃,建议用 Application 模式)
- Application 模式:用户
main()方法直接在 JobManager 端执行,Client 无需下载依赖,大幅降低网络传输压力
四、四层图转化关系

用户代码
│
│ env.execute() 触发
▼
StreamGraph ← 用户 API 直接生成,描述算子逻辑拓扑(含所有 Transformation)
│
│ 算子链合并(Operator Chain)
▼
JobGraph ← Client 端生成,是跨网络传输的基本单位,减少序列化开销
│
│ 按并行度展开(每个 JobVertex → N 个 ExecutionVertex)
▼
ExecutionGraph ← JobManager 端维护,包含完整调度状态机和执行状态
│
│ 部署到 TaskManager
▼
Physical Graph ← 运行在 TM 上的实际 Task 实例,通过 Network Buffer 流转数据
| 图层 | 生成位置 | 核心特征 |
|---|---|---|
| StreamGraph | Client 端 | 算子级逻辑拓扑,保留完整语义,未考虑并行度 |
| JobGraph | Client 端 | 合并 OperatorChain,是提交给集群的基本单位 |
| ExecutionGraph | JobManager 端 | 并行展开,每个并发实例为独立 ExecutionVertex |
| Physical Graph | TaskManager 端 | 实际运行的 Task,含 Network Buffer 连接关系 |
参考:Apache Flink 官方文档 https://flink.apache.org/docs/
更多推荐
所有评论(0)