news 2026/4/16 8:43:44

【Flink】Flink架构深度剖析:JobManager与TaskManager

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Flink】Flink架构深度剖析:JobManager与TaskManager

Flink架构深度剖析:JobManager与TaskManager

前言

上一篇我们成功跑起了第一个 Flink 程序,但你有没有想过:当你点击"运行"后,代码是怎么被执行的?数据是怎么在多个节点之间流动的?

这篇文章我们就来揭开 Flink 的"底裤"——深入剖析 Flink 的架构设计。理解了架构,你才能知道程序为什么慢、哪里出了问题、怎么调优。

放心,我会用大白话 + 图解的方式来讲,保证你看完能说清楚 Flink 的架构。

🏠个人主页:你的主页


目录

  • 一、Flink架构全景图
  • 二、JobManager详解
  • 三、TaskManager详解
  • 四、作业提交与执行流程
  • 五、Task与SubTask
  • 六、算子链与任务槽
  • 七、并行度的理解与配置
  • 八、高可用架构
  • 九、总结

一、Flink架构全景图

Flink 采用经典的主从架构(Master-Slave),和 Hadoop、Spark 类似。先看一张全景图:

┌─────────────────────────────────────────────────────────────────────────┐ │ Flink 集群架构 │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ JobManager(主节点) │ │ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ │ │ Dispatcher │ │ResourceManager│ │ JobMaster │ │ │ │ │ │ 接收作业提交 │ │ 资源管理 │ │ 作业调度执行 │ │ │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ 分配任务 │ │ ↓ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ TaskManager 1 │ │ TaskManager 2 │ │ TaskManager 3 │ │ │ │ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │ │ │ │ │Slot│ │Slot│ │ │ │Slot│ │Slot│ │ │ │Slot│ │Slot│ │ │ │ │ └────┘ └────┘ │ │ └────┘ └────┘ │ │ └────┘ └────┘ │ │ │ │ 执行任务 │ │ 执行任务 │ │ 执行任务 │ │ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ │ │ │ │ └──────────────────────┴──────────────────────┘ │ │ 数据交换 │ └─────────────────────────────────────────────────────────────────────────┘

一句话概括

  • JobManager= 老板,负责接活、分配任务、监督进度
  • TaskManager= 员工,负责干活、汇报状态

二、JobManager详解

JobManager 是 Flink 集群的大脑,负责整个作业的管理和协调。它由三个核心组件构成:

2.1 三大核心组件

┌─────────────────────────────────────────────────────────────────┐ │ JobManager │ │ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ Dispatcher │ │ │ │ • 提供 REST 接口,接收客户端提交的作业 │ │ │ │ • 为每个作业启动一个 JobMaster │ │ │ │ • 负责 Flink WebUI 展示 │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ ResourceManager │ │ │ │ • 管理集群资源(TaskManager 的 Slot) │ │ │ │ • 负责 TaskManager 的注册与心跳 │ │ │ │ • 与外部资源管理器对接(YARN/K8s/Mesos) │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ JobMaster │ │ │ │ • 每个作业一个 JobMaster │ │ │ │ • 将 JobGraph 转换为 ExecutionGraph │ │ │ │ • 调度 Task 到 TaskManager 执行 │ │ │ │ • 协调 Checkpoint │ │ │ └────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘

2.2 用大白话解释

打个比方,JobManager 就像一个项目管理部门

组件角色类比职责
Dispatcher前台接待接收客户需求(作业),分配给项目经理
ResourceManagerHR部门管理员工(TaskManager),分配工位(Slot)
JobMaster项目经理负责具体项目,拆解任务、分配工作、跟进进度

2.3 JobManager 的核心职责

  1. 接收作业提交:通过 REST API 或命令行接收用户提交的 Jar 包
  2. 生成执行计划:将用户代码转换为可执行的任务图
  3. 调度任务:将任务分配到具体的 TaskManager 执行
  4. 协调 Checkpoint:触发检查点,协调各 Task 进行状态快照
  5. 故障恢复:当 Task 失败时,重新调度执行

三、TaskManager详解

TaskManager 是 Flink 集群的劳动力,负责实际执行计算任务。

3.1 TaskManager 结构

┌─────────────────────────────────────────────────────────────────┐ │ TaskManager │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Task Slot 1 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ SubTask │ │ SubTask │ │ SubTask │ ← 同一 Slot 可 │ │ │ │ │ (Source)│→ │ (Map) │→ │ (Sink) │ 运行多个 SubTask │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Task Slot 2 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ SubTask │→ │ SubTask │→ │ SubTask │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ Network Buffer │ │ Memory Pool │ │ │ │ 网络数据缓冲 │ │ 内存管理 │ │ │ └──────────────────────┘ └──────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘

3.2 什么是 Task Slot?

Slot(任务槽)是 TaskManager 中资源分配的基本单位。你可以把它理解为"工位":

  • 一个 TaskManager 可以有多个 Slot
  • 每个 Slot 拥有固定的内存资源
  • 不同 Slot 之间内存隔离,CPU 共享

默认配置:每个 TaskManager 有 1 个 Slot。生产环境通常配置 2-4 个。

# flink-conf.yamltaskmanager.numberOfTaskSlots:2

3.3 TaskManager 的核心职责

  1. 执行任务:运行 JobManager 分配下来的 SubTask
  2. 数据交换:与其他 TaskManager 交换数据(Shuffle)
  3. 状态管理:维护本地状态,参与 Checkpoint
  4. 心跳汇报:定期向 JobManager 汇报自身状态

3.4 TaskManager vs TaskSlot vs Task

这三个概念很容易混淆,我们来理清楚:

概念是什么类比
TaskManager一个 JVM 进程一个员工
Task SlotTM 中的资源单位员工的工位
Task一个算子的并行实例一项具体工作
SubTaskTask 的一个并行度实例工作的一个子任务

举例

  • 一个 Flink 集群有 3 个 TaskManager
  • 每个 TaskManager 有 2 个 Slot
  • 那么集群总共有 6 个 Slot,最多可以同时执行 6 个并行任务

四、作业提交与执行流程

当你在 IDEA 点击运行,或者用flink run提交作业时,背后发生了什么?

4.1 完整流程图

┌──────────┐ ┌──────────────────────────────────────────────────────┐ │ Client │ │ JobManager │ │ │ │ │ │ 用户代码 │ │ Dispatcher ResourceManager JobMaster │ └────┬─────┘ └──────┬──────────────┬──────────────────┬─────────────┘ │ │ │ │ │ ① 提交 JobGraph │ │ │ │─────────────────→│ │ │ │ │ │ │ │ │ ② 启动 JobMaster │ │ │────────────────────────────────→│ │ │ │ │ │ │ │ ③ 申请 Slot │ │ │ │←──────────────────│ │ │ │ │ │ │ │ ④ 分配 Slot │ │ │ │──────────────────→│ │ │ │ │ │ │ │ │ ⑤ 部署 Task │ │ │ │─────────┐ │ │ │ │ │ │ │ │ │ ↓ │ │ │ ┌────────────────────┐ │ │ │ │ TaskManager │ │ │ │ │ 执行 Task │ │ │ │ └────────────────────┘

4.2 流程详解

第一步:客户端提交作业

// 用户代码env.execute("My Flink Job");

当调用execute()时,客户端会:

  1. 将用户代码编译成StreamGraph(流图)
  2. 优化成JobGraph(作业图)
  3. 通过 REST API 提交给 Dispatcher

第二步:Dispatcher 接收作业

Dispatcher 收到 JobGraph 后,为这个作业启动一个专属的JobMaster

第三步:JobMaster 申请资源

JobMaster 分析 JobGraph,计算需要多少个 Slot,然后向 ResourceManager 申请。

第四步:ResourceManager 分配 Slot

ResourceManager 检查有哪些 TaskManager 有空闲 Slot,分配给 JobMaster。

如果 Slot 不足:

  • Standalone 模式:等待或报错
  • YARN/K8s 模式:动态申请新的 TaskManager

第五步:部署 Task 执行

JobMaster 将 Task 部署到分配好的 Slot 上,TaskManager 开始执行。

4.3 三种图的转换

用户代码在提交过程中,会经历三次转换:

用户代码 │ │ 客户端 ↓ StreamGraph(流图) │ │ 客户端优化 ↓ JobGraph(作业图) │ │ JobMaster ↓ ExecutionGraph(执行图) │ │ 调度执行 ↓ 物理执行
图类型生成位置特点
StreamGraph客户端最原始的逻辑图,一个算子一个节点
JobGraph客户端优化后的图,可合并的算子会chain在一起
ExecutionGraphJobMaster并行化后的图,每个节点按并行度展开

五、Task与SubTask

5.1 什么是 Task?

Task是 Flink 执行的基本单位。但这里的 Task 不是指单个算子,而是算子链(Operator Chain)

Flink 会把可以合并的算子串成一个 Task,减少数据传输开销。

5.2 什么是 SubTask?

SubTask是 Task 的并行实例。如果一个 Task 的并行度是 3,那么它会有 3 个 SubTask。

┌────────────────────────────────────────────────────────────────┐ │ 一个 Task(算子链) │ │ │ │ Source → Map → Filter (这三个算子被合并成一个 Task) │ │ │ │ 并行度 = 3 │ │ │ │ ┌─────────────────┐ │ │ │ SubTask 0 │ ← 处理 partition 0 的数据 │ │ │ Source→Map→Filter │ │ └─────────────────┘ │ │ ┌─────────────────┐ │ │ │ SubTask 1 │ ← 处理 partition 1 的数据 │ │ │ Source→Map→Filter │ │ └─────────────────┘ │ │ ┌─────────────────┐ │ │ │ SubTask 2 │ ← 处理 partition 2 的数据 │ │ │ Source→Map→Filter │ │ └─────────────────┘ │ └────────────────────────────────────────────────────────────────┘

5.3 Task 数量计算

假设有如下作业:

source.setParallelism(2).map(...).setParallelism(2).keyBy(...).reduce(...).setParallelism(3).sink(...).setParallelism(3);

假设 source → map 被 chain 成一个 Task,reduce → sink 被 chain 成一个 Task:

  • Task 1(source-map):2 个 SubTask
  • Task 2(reduce-sink):3 个 SubTask
  • 总共需要 5 个 Slot

六、算子链与任务槽

6.1 什么是算子链(Operator Chain)?

算子链是 Flink 的一个重要优化。它把多个算子合并在一起,在同一个线程中执行,避免了:

  • 线程切换开销
  • 数据序列化/反序列化开销
  • 网络传输开销
优化前: ┌────────┐ 网络 ┌────────┐ 网络 ┌────────┐ │ Source │ ────────→ │ Map │ ────────→ │ Filter │ └────────┘ └────────┘ └────────┘ ↓ ↓ ↓ 线程1 线程2 线程3 优化后(算子链): ┌──────────────────────────────────────────┐ │ Source → Map → Filter │ ← 同一线程执行 │ 算子链 │ └──────────────────────────────────────────┘ ↓ 线程1

6.2 算子链的条件

不是所有算子都能被 chain 在一起,需要满足以下条件:

  1. 上下游并行度相同
  2. 数据传输方式是 Forward(一对一传输,非 shuffle)
  3. 在同一个 SlotSharingGroup
  4. 没有被用户禁用chain

6.3 手动控制算子链

有时候你可能需要手动控制算子链的行为:

// 禁用当前算子与下游的 chaindataStream.map(...).disableChaining();// 从当前算子开始一个新的 chaindataStream.map(...).startNewChain();// 全局禁用算子链env.disableOperatorChaining();

什么时候需要手动控制?

  • 某个算子特别重(如调用外部 API),需要单独监控
  • 排查性能问题,想看每个算子的耗时

6.4 Slot 共享(Slot Sharing)

默认情况下,Flink 允许不同 Task 的 SubTask 共享同一个 Slot

┌────────────────────────────────────────────────────────┐ │ Slot │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Source │ │ Map │ │ Sink │ │ │ │ SubTask0│ │ SubTask0│ │ SubTask0│ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ ← 三个不同 Task 的 SubTask 共享一个 Slot │ └────────────────────────────────────────────────────────┘

好处

  • 充分利用 Slot 资源
  • 减少需要的 Slot 数量
  • 同一 Slot 内数据传输不走网络

计算公式

需要的 Slot 数 = max(各算子的并行度)

例如 Source 并行度 2,Map 并行度 3,Sink 并行度 3,那么需要 3 个 Slot(而不是 2+3+3=8)。


七、并行度的理解与配置

7.1 什么是并行度?

并行度(Parallelism)就是一个算子同时有多少个实例在并行执行。

并行度 = 1 并行度 = 3 ┌─────────┐ ┌─────────┐ │ Map │ │ Map 0 │ │ │ ← 单实例 ├─────────┤ └─────────┘ │ Map 1 │ ← 三个实例并行 ├─────────┤ │ Map 2 │ └─────────┘

7.2 并行度的四种设置方式

优先级从高到低:

// 1. 算子级别(最高优先级)dataStream.map(...).setParallelism(2);// 2. 执行环境级别env.setParallelism(3);// 3. 提交时指定// flink run -p 4 xxx.jar// 4. 配置文件(最低优先级)// flink-conf.yaml: parallelism.default: 1

7.3 如何设置合理的并行度?

经验法则

场景并行度建议
开发测试1-2,方便调试
生产环境等于或略小于可用 Slot 数
Kafka Source等于 Kafka 分区数
CPU 密集型接近 CPU 核心数
IO 密集型可以超过 CPU 核心数

注意:Source 的并行度不能超过 Kafka 分区数,否则多余的 SubTask 会空转。

7.4 并行度实例

// 假设 Kafka 有 6 个分区,集群有 12 个 Slotenv.setParallelism(6);// 全局默认并行度KafkaSource<String>source=KafkaSource.<String>builder()// ....build();env.fromSource(source,WatermarkStrategy.noWatermarks(),"Kafka Source").setParallelism(6)// Source 并行度 = Kafka 分区数.map(...).setParallelism(12)// Map 可以更高.keyBy(...).reduce(...).setParallelism(6)// 聚合操作并行度适中.addSink(...).setParallelism(6);

八、高可用架构

生产环境中,JobManager 是单点,一旦挂掉,整个作业就停了。Flink 支持HA(High Availability)模式。

8.1 Standalone HA

┌─────────────────────────────────────────────────────────────────┐ │ ZooKeeper 集群 │ │ (Leader 选举) │ │ │ │ │ ┌─────────────┼─────────────┐ │ │ ↓ ↓ ↓ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │JobManager │ │JobManager │ │JobManager │ │ │ │ (Leader) │ │ (Standby) │ │ (Standby) │ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ │ 元数据存储:HDFS / S3 / NFS │ └─────────────────────────────────────────────────────────────────┘

工作原理

  1. 多个 JobManager 启动,通过 ZK 选举 Leader
  2. Leader 负责实际工作,Standby 待命
  3. 作业元数据(JobGraph、Checkpoint 路径)存储在共享存储
  4. Leader 挂掉后,Standby 接管,从共享存储恢复

8.2 YARN/K8s HA

在 YARN 或 K8s 上,HA 更简单:

  • YARN:ApplicationMaster(JobManager)失败后,YARN 会自动重启
  • K8s:通过 Deployment 配置副本数,Pod 失败自动重建

8.3 配置示例

# flink-conf.yaml# 开启 HAhigh-availability:zookeeperhigh-availability.zookeeper.quorum:zk1:2181,zk2:2181,zk3:2181high-availability.zookeeper.path.root:/flinkhigh-availability.storageDir:hdfs:///flink/ha/high-availability.cluster-id:my-flink-cluster

九、总结

这篇文章我们深入了解了 Flink 的架构设计:

核心组件

组件职责类比
JobManager作业管理、任务调度、协调 Checkpoint老板/项目经理
TaskManager执行任务、数据交换、状态管理员工
Dispatcher接收作业、启动 JobMaster前台
ResourceManager管理资源、分配 SlotHR
JobMaster单个作业的调度执行项目经理

核心概念

概念说明
Task SlotTaskManager 中的资源单位,内存隔离
Task算子链,执行的基本单位
SubTaskTask 的并行实例
算子链多个算子合并,减少开销
并行度算子的并行实例数
Slot 共享不同 Task 可共享 Slot

作业执行流程

  1. 客户端生成 JobGraph,提交给 Dispatcher
  2. Dispatcher 启动 JobMaster
  3. JobMaster 向 ResourceManager 申请 Slot
  4. ResourceManager 分配 Slot
  5. JobMaster 部署 Task 到 TaskManager 执行

下一篇文章,我们将学习Flink 的编程模型:DataStream 与 DataSet,深入理解流批一体的 API 设计。


热门专栏推荐

  • Agent小册
  • Java基础合集
  • Python基础合集
  • Go基础合集
  • 大数据合集
  • 前端小册
  • 数据库合集
  • Redis 合集
  • Spring 全家桶
  • 微服务全家桶
  • 数据结构与算法合集
  • 设计模式小册
  • Ai工具小册

等等等还有许多优秀的合集在主页等着大家的光顾,感谢大家的支持


文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😊
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🙏
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🌟

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/4 1:24:32

(21)手写Spring框架

Spring IoC容器的实现原理&#xff1a;工厂模式 解析XML 反射机制。 我们给自己的框架起名为&#xff1a;myspring&#xff08;我的春天&#xff09; 第一步&#xff1a;创建模块myspring 采用Maven方式新建Module&#xff1a;myspring打包方式采用jar&#xff0c;并且引入do…

作者头像 李华
网站建设 2026/4/12 22:35:05

MATLAB中两种常用的纹理特征提取方法:灰度共生矩阵和灰度差分统计

1. 灰度共生矩阵 灰度共生矩阵是迄今为止最经典、最常用的纹理分析方法。它通过计算图像中特定方向和距离的像素对出现的频率来描述纹理。 原理简介 GLCM是一个方阵&#xff0c;其大小由图像的最大灰度级决定。矩阵中的元素 P(i, j | d, θ) 表示在给定空间距离 d 和方向 θ 时…

作者头像 李华
网站建设 2026/3/31 4:27:06

2025年12月9日,OpenAI发布ChatGPT-5.2:未来已经到来,AI改变生活

2025年12月9日&#xff0c;OpenAI迎来了一个重磅发布——ChatGPT-5.2。作为继ChatGPT-5.0之后的又一重要版本更新&#xff0c;5.2不仅带来了更强的技术功能&#xff0c;还让人工智能在各个领域的应用变得更加深入人心。通过强大的多模态能力、超高的情感理解、无缝的跨行业适配…

作者头像 李华
网站建设 2026/4/16 7:03:57

.NET 10 网络堆栈深度架构解析:HTTP/3、性能优化与后量子加密的融合演进

T 10 的发布&#xff0c;微软不仅是在更新一个开发框架&#xff0c;更是在重新定义云原生时代的网络通信标准。本次更新的核心理念紧扣“更现代、更高效、更开发者友好”的三大支柱&#xff0c;标志着.NET 网络堆栈从传统的 TCP/IP 依赖向以 UDP 为基础的 QUIC 协议、后量子加密…

作者头像 李华
网站建设 2026/4/15 17:11:29

有哪些永久免费进销存出入库管理系统?推荐象过河软件

对于中小微企业和个体商户而言&#xff0c;进销存出入库管理是经营的核心环节&#xff0c;可传统手工记录模式易出现数据错漏、库存积压或缺货的问题&#xff0c;而付费进销存系统又会增加经营成本&#xff0c;因此不少商家都在寻找永久免费的进销存出入库管理系统。2025 年&am…

作者头像 李华
网站建设 2026/4/10 21:01:41

Python+Vue的基于推荐算法的在线课程推荐系统 Pycharm django flask

收藏关注不迷路&#xff01;&#xff01;需要的小伙伴可以发链接或者截图给我 项目介绍 本系统共有管理员,用户2个角色&#xff0c;具体功能如下&#xff1a; 1.管理员角色的功能主要包括管理员登录&#xff0c;用户管理&#xff0c;课程信息管理&#xff0c;课程类型管理&…

作者头像 李华