Flink 集群架构
文章目录
一、架构总览:Master-Worker 模式
Flink 集群采用经典的 Master-Worker(主从)架构:
┌─────────────────────────────────────────────────────────────┐
│ Flink 集群 │
│ │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ JobManager │◄────────│ TaskManager(s) │ │
│ │ (Master) │ RPC │ (Worker) │ │
│ │ │────────►│ │ │
│ │ · 资源管理 │ │ · Task Slot 1 (线程) │ │
│ │ · 作业调度 │ │ · Task Slot 2 (线程) │ │
│ │ · Checkpoint │ │ · Task Slot N (线程) │ │
│ └──────┬───────┘ │ · 数据 Shuffle │ │
│ │ │ · 内存管理 │ │
│ │ └──────────────────────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ Client │ 提交 JAR + JobGraph │
│ │ (用户侧) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
| 角色 | 数量 | 职责 |
|---|---|---|
| JobManager(Master) | 1 个(HA 可多个) | 集群管理、资源调度、作业执行协调、Checkpoint 协调 |
| TaskManager(Worker) | N 个(多节点) | 提供计算资源(Task Slot),执行具体 Task |
| Client(客户端) | — | 接收用户提交,生成 JobGraph,连接 JobManager |
二、JobManager 详解
JobManager 是集群的大脑,内部由多个核心组件构成:
2.1 JobManager 六大部分
JobManager
│
┌────────┬───────────┼───────────┬──────────┬──────────┐
│ │ │ │ │ │
Checkpoint ExecutionGraph 调度器 Dispatcher ResourceMgr Akka RPC
Coordinator
| 组件 | 功能 |
|---|---|
| Checkpoint Coordinator | 协调各 TaskManager 的 Checkpoint 执行,触发分布式快照 |
| ExecutionGraph | 将逻辑 JobGraph 转换为物理执行计划 |
| Task 调度器 | 将 Task 拆分并部署到 TaskManager 的 Task Slot 上运行 |
| Job Dispatcher | 接收 Client 提交的 JobGraph,分拆成不同作业 |
| ResourceManager | 资源管理器,不同部署模式有不同实现(Standalone/YARN/K8s) |
| Akka RPC(ActorSystem) | 所有组件间远程通信的基础框架 |
2.2 TaskManager 注册与心跳
TaskManager 启动 → 向 JobManager 注册(RPC)→ JobManager 记录信息
│
┌────────────┘
▼
持续 Heartbeat(心跳检测)
- TaskManager 主动向 JobManager 注册
- 注册后 JobManager 持续维护 TaskManager 信息
- 通过心跳(Heartbeat)检测 TaskManager 存活状态
2.3 ResourceManager 的多种实现
| 部署模式 | ResourceManager 实现 |
|---|---|
| Standalone | 内置实现 |
| YARN | YarnResourceManager |
| Kubernetes | K8sResourceManager |
三、TaskManager 详解
TaskManager 是实际干活的 Worker 节点。一个 TaskManager 就是一个 JVM 进程。
3.1 TaskManager 内部组件
TaskManager (JVM 进程)
│
┌──────────┬───────────┼───────────┬──────────┬──────────┐
│ │ │ │ │ │
Task Slots Shuffle Akka Netty-Based Memory 注册/心跳
(线程池) Environment RPC NetworkStack Manager
| 组件 | 功能 |
|---|---|
| Task Slots | 计算资源的基本单位,本质是线程池中的线程,每个 Slot 运行一组 Task |
| Shuffle Environment | 数据跨节点传输(类似 MR/Spark 的 Shuffle) |
| Akka RPC | 与 JobManager 的控制面通信 |
| Netty NetworkStack | 基于 Netty 实现的数据面网络传输协议栈 |
| Memory Manager | 内存管理(序列化/反序列化),申请/释放内存 |
| 注册与心跳 | 启动后向 JobManager 注册,持续心跳 |
3.2 控制面 vs 数据面通信
| 通信类型 | 通道 | 协议 | 内容 |
|---|---|---|---|
| 控制面 | Akka RPC(ActorSystem) | RPC | 任务调度、状态上报、心跳 |
| 数据面 | Netty NetworkStack | 网络传输 | TaskManager 之间传输数据(Shuffle) |
这是 Flink 架构设计的重要解耦:控制指令走 RPC,数据传输走 Netty,各司其职。
3.3 Task Slot 的本质
TaskManager = JVM 进程
│
├── Task Slot 1(线程) ← 运行一组 Task
├── Task Slot 2(线程) ← 运行一组 Task
└── Task Slot N(线程) ← 运行一组 Task
| 概念 | 解释 |
|---|---|
| TaskManager | 一个 JVM 进程 |
| Task Slot | 进程内的一个线程(本质上是线程池中的线程) |
| Task | 作业拆分后的最小执行单元,在 Slot 中运行 |
JobManager 向 TaskManager 申请 Slot 资源,获得 Slot 后部署 Task 执行。
四、Client 详解
Client 是用户与 Flink 集群的桥梁。
4.1 Client 的核心职责
| 步骤 | 动作 | 说明 |
|---|---|---|
| 1 | 接收用户提交的 Application JAR | 通过 flink run 命令提交 |
| 2 | 反射调用 main 方法 | 在 Client 本地进程执行用户程序 |
| 3 | 生成 JobGraph(DAG) | 将 DataStream/Table API/SQL 转换为统一的 DAG 表达 |
| 4 | 提交 JobGraph 到 JobManager | 通过 Akka RPC 提交 |
| 5 | 分发依赖 JAR | 将用户程序的依赖 JAR 包上传到 JobManager |
| 6 | 获取 JobClient | 用于与 JobManager 通信,查询作业执行状态 |
4.2 Client 端的执行环境
在编写 Flink 程序时,首先需要创建执行环境:
// 用户代码中
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
这个 ExecutionEnvironment 在 Client 端创建,负责:
- 将用户程序在本地进程中执行
- 生成 StreamGraph(逻辑图)
- 转换为 JobGraph 提交
4.3 ExecutionEnvironment 的类型
| 类型 | 说明 |
|---|---|
| 本地执行器 | 本地开发测试 |
| 远程执行器 | 连接远程集群 |
| YARN 执行器 | 提交到 YARN 集群 |
五、JobGraph —— 作业的 DAG 表示
这是理解 Flink 作业提交流程的核心。
5.1 作业提交全流程
用户代码(Java/Scala)
│
▼ 反射调用 main 方法
Client 本地进程执行
│
▼ StreamGraph(逻辑 DataFlow)
生成 StreamGraph
│
▼ 转换 + 并行度分解
生成 JobGraph(DAG 图)
│
▼ 提交到 JobManager
JobManager 调度
│
▼ 转换为 ExecutionGraph(物理执行计划)
TaskManager 执行
5.2 StreamGraph → JobGraph → ExecutionGraph
StreamGraph JobGraph ExecutionGraph
(逻辑流水线) (逻辑 DAG + 并行度) (物理执行计划)
│ │ │
Source → Map → KeyBy → Sink 每个算子标明并行度 每个并行实例对应一个 Task
分布在 Task Slot 中
| 图 | 生成位置 | 内容 |
|---|---|---|
| StreamGraph | Client 端 | 描述数据转换逻辑(Source → Transform → Sink) |
| JobGraph | Client 端 | 加入并行度信息,形成最终提交给 JobManager 的 DAG |
| ExecutionGraph | JobManager 端 | 物理执行计划,每个算子实例对应具体 Task,分配到 Task Slot |
5.3 JobGraph 的三个核心特点
| 特点 | 说明 |
|---|---|
| DAG 表达 | 用有向无环图(DAG)表达用户程序的逻辑拓扑 |
| 统一抽象 | 无论用 DataStream API、Table API 还是 Flink SQL,最终都转换为统一的 JobGraph |
| 职责分离 | Client 负责静态编译(生成 JobGraph),JobManager 负责动态执行(调度 Task) |
JobGraph 的「统一抽象」是 Flink 支持多 API 接口的关键——不管你用什么 API 编写,最终都收敛为同一个 DAG 结构提交。
六、完整作业提交流程(端到端)
1. 用户编写 Flink 程序
│
2. flink run xxx.jar → Client
│
3. Client 反射调用 main 方法(本地执行)
│
4. 生成 StreamGraph → JobGraph
│
5. 通过 Akka RPC 提交 JobGraph + 依赖 JAR → JobManager.Dispatcher
│
6. JobManager 将 JobGraph → ExecutionGraph
│
7. JobManager 向 TaskManager 申请 Task Slot
│
8. ExecutionGraph 中的 Task 分配到各 TaskManager 的 Slot 中执行
│
9. TaskManager 之间通过 Netty 进行数据 Shuffle
│
10. Client 通过 JobClient 查询作业状态
七、核心组件速查表
| 组件 | 位置 | 一句话功能 |
|---|---|---|
| JobManager | Master 节点 | 集群大脑,管资源、管调度、管 Checkpoint |
| TaskManager | Worker 节点 | 干活节点,提供 Slot 执行 Task |
| Task Slot | TaskManager 内 | 计算资源基本单位(线程级别) |
| Client | 用户侧 | 接收作业、生成 JobGraph、提交到集群 |
| JobGraph | Client 生成 | 用户程序的 DAG 表达 + 并行度 |
| ExecutionGraph | JobManager 生成 | 物理执行计划 |
| Akka RPC | 全局 | 控制面通信框架 |
| Netty NetworkStack | TaskManager 间 | 数据面传输协议栈 |
| Checkpoint Coordinator | JobManager 内 | 协调分布式快照 |
| ResourceManager | JobManager 内 | 多部署模式资源管理 |
| Memory Manager | TaskManager 内 | 序列化/反序列化 + 内存管理 |
| Shuffle Environment | TaskManager 内 | 跨节点数据传输 |
八、小结
本文是 Flink 架构的「骨架图」,信息量很大:
- Flink 采用 Master-Worker 架构,JobManager(主)+ TaskManager(从)
- JobManager 六大组件协同工作,ResourceManager 根据部署模式有多套实现
- TaskManager 是 JVM 进程,Task Slot 是线程池中的线程,控制面走 Akka、数据面走 Netty
- Client 负责反射执行 main 方法、生成 JobGraph、提交到集群
- StreamGraph → JobGraph → ExecutionGraph 三重转换,实现逻辑到物理的解耦
- JobGraph 统一抽象:无论用哪种 API 编写,最终都是一个 DAG