Flink中TaskManager与Slots的关系

一、基本概念

1、TaskManager

Flink 采用 Master-Slave 主从架构,其中 JobManager 作为集群 Master节点 ,主要负责任务协调资源分配TaskWorker (TaskManager) 作为Salve节点,用于执行流task

JobManager控制一个应用程序执行主进程,相当于集群的Master节点,且整个集群有且只有一个活跃的 JobManagerJobManager 负责整个 Flink 集群任务的调度以及资源的管理

Flink TaskManager 执行作业流的 task,并且缓存和交换数据流,TaskManager 负责执行用户代码。根据实际需求为 TaskManager 配置内存将有助于减少 Flink 的资源占用,增强作业运行的稳定性。

2、Slots

Flink中每一个worker(TaskManager)都是一个 JVM进程 ,它可能会在独立的线程上执行一个或多个subtask。为了控制一个TaskManager能接收多少个task,TaskManager通过task slot来进行控制(一个TaskManager至少有一个task slot)。

二、TaskManager与Slots的关系

每个task slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分成三份给各个slot。资源slot化意味着一个subtask将不需要跟来自其他job的subtask竞争被管理的内存,取而代之的是它将拥有一定数量的内存储备。需要注意的是,这里不会涉及到CPU的隔离,slot目前仅仅用来隔离task的受管理的内存。

通过调整task slot的数量,允许用户定义subtask之间如何互相隔离。如果一个TaskManager一个slot,那将意味着每个task group运行在独立的JVM中(该JVM可能是通过一个特定的容器启动的),而一个TaskManager多个slot意味着更多的subtask可以共享同一个JVM。而在同一个JVM进程中的task将共享TCP连接(基于多路复用)和心跳消息。它们也可能共享数据集和数据结构,因此这减少了每个task的负载。

默认情况下,Flink允许子任务共享slot,即使它们是不同任务的子任务(前提是它们来自同一个job)。 这样的结果是,一个slot可以保存作业的整个管道

Task Slot是静态的概念,是指TaskManager具有的并发执行能力,可以通过参数taskmanager.numberOfTaskSlots进行配置;而并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,可以通过参数parallelism.default进行配置。

假设现在有这样一个程序:

t1

其任务划分大概如下图所示:

image-20230719150157728

假设我们此时以集群部署三台TaskManager,每台TaskManager划分3个Slot,其执行流程图大致如下图所示:

image-20230719150310433

比如此时我们的Job是 A(source+flatMap) —> B(keyBy) —> C(sum+print) 这样一个流,在单节点的情况下是一个串行流。但在分布式情况下,Job的执行流程可以大致理解为一个有向无环图,其执行流程可以如下图所示:

image-20230719152544567

可以看到,Flink允许子任务共享Slot,即使它们是不同任务的子任务,如上图中的D —> B —> C 流,其与 A —> B —> C 流并不是同一个流,但它们仍能共享同一个 Slot。