Flink TM、subTask、JVM、算子链、slot、slot组的关系
1.TaskManager与JVM
- TaskManager是根据Flink集群分配的,本地测试
LocalExecutionEnvironment默认只会产生一个TaskManager。
- 一个TaskManager对应一个JVM,不同的TaskManger是不同的JVM,完全隔离。(同一个JVM的静态变量会共享)
- 同一JVM内的资源(静态变量、类加载器、数据库连接池等)可被所有Subtask共享;
- 不同JVM间无任何内存共享,需通过Flink分布式状态(如RocksDB)或外部存储(如Redis)传递数据。
2.算子链Operator Chain
- 算子链(Operator Chain)的形成需满足以下
- 两个算子的并行度相同
- 后一个算子的输入仅来自前一个算子(无其他上游算子);
- 两个算子处于同一 Slot 共享组(默认都是
default组);
- 前一个算子到后一个算子的连接无重分区操作(如
keyBy、rebalance、shuffle等会打破算子链,forward连接则允许)。
3.TaskManger的Slot与subTask
- 一个TaskManager下会有多个slot,这些slot是可以共享TaskManager内存的(数据结构、对象、变量等)。但每个Slot也有自己独立的执行上下文和一定的资源隔离,并不是完全无限制地共享所有内存。
- slot是TaskManager中用于并行执行任务的资源单位,每个slot可以运行一个|多个任务
- subtask与Slot的关系:
- subtask是“算子的并行执行实例”(如并行度3的
Map算子对应3个MapSubtask),subTask本质是一个Java对象;
- subtask运行在Slot上,一个Slot可运行多个subtask(需满足:① 来自同一作业;② 处于同一Slot共享组;③ 无资源配额冲突);
- 核心对应关系:当前算子的Subtask数量 = 该算子的并行度。

- Slot 是 TM 的 “资源切片”,其 “资源隔离” 并非 “内存完全隔离”,而是 “资源配额隔离”:
- 共享的资源:TM 的 JVM 堆内存、堆外内存、类加载器、静态资源(如数据库连接池实例);
- 隔离的资源:Flink 通过配置为每个 Slot 分配固定的内存配额(如
taskmanager.memory.task.heap.size)、CPU 权重,避免单个 Slot 耗尽 TM 的全部资源。
4.slot组
- slot组是逻辑隔离机制,通过
算子.slotSharingGroup("group-name")指定,目的是将高负载算在单独放在一个组内,避免被其他算子抢占资源。
- 调度规则:不同Slot组的任务必须分配到独立的Slot;同一Slot组的任务可共享Slot(默认
default组,实现资源复用)。
- 内存共享的核心依据是
是否属于同一个TaskManager
- 同一 TM 内的所有 Slot(无论是否同组):共享 TM 的 JVM 内存(如静态变量、共享对象);
- 不同 TM 的 Slot(无论是否同组):不共享内存(JVM 隔离)。
- 不同slot组的,但在同一个TaskManager下的slot之间,共享变量的规则如下:
- 如果Map是全局静态变量,那么在同一个
TaskManager下的所有slot都可以访问和修改
- 如果Map是在
TaskManager 的初始化阶段open()创建且被所有 Slot 共享,那么不同 Slot 组的 Slot 也可以共享这个Map
- 如果Map是在每个 Slot 内部单独创建的,那么不同 Slot 组的 Slot 各自拥有独立的Map实例,它们之间不会共享.
5.slot、TM数量计算
- 所需总slot的数量=每个slot组的最大并行度的总和
- TM数量=ceil(所需总slot的数量/每个TM配置的slot数)