任务槽 TaskSlots
Flink中每个TaskManager都是一个JVM进程,它可以启动多个独立的现成并执行多个子任务subask
很显然TaskManager的计算资源是有限的,并行的任务越多,每个线程的资源就会越少。那么一个TaskManager到底能并行处理多少个任务呢?为了控制并发量,我们需要在TaskManager上对每个任务运行所占用的资源做出明确划分,这就是所谓的任务槽。
每个任务槽task slot其实表示了TaskManager拥有计算资源的一个固定大小的自己。这些资源就是用来独立执行一个子任务的。
假如一个TaskManager有三个slot,那么它会将管理的内存平均分成三份,每个slot独自占据一份。这样一来,我们在slot上执行一个子任务时,相当于划定了一块内存“专款专用”,就不需要跟来自其他作业的任务区竞争内存资源了。
比如当前有五个任务,每个TaskManager提供三个slot 那么需要启动2个TaskManager
任务槽数量的设置
flink-conf.yaml配置文件中
# 默认1
taskmanager.numberOfTaskSlots: 8
需要注意的时,slot目前仅仅用来隔离内存,不会涉及CPU的隔离。在具体应用时,可以将slot数量配置为机器的CPU核心数,尽量避免不同任务之间对CPU的竞争。这也是开发环境默认并行度为机器CPU数量的原因。
一个TaskManager 1个CPU 3G内存 3个slot:每个slot 1G内存 CPU共享
TaskManager可以理解为一个房子 三个slot理解为三个房间 CPU理解为一个卫生间,一个卫生间 三个房间公共使用
任务对任务槽的共享
在同一个作业中,不同任务节点(不同算子)的并行子任务,就可以放到同一个slot上执行
只要属于同一个作业,那么对于不同任务节点(算子)的并行子任务,就可以放到同一个slot上执行。
- 一个slot理解一个房间,一个房间可以睡多个人 也就是可以执行多个不同算子子任务
slot特点
- 均分隔离内存,不隔离cpu
- 可以共享
- 同一个job中,不同算子的子任务,才可以共享
- 前提是,属于同一个slot共享组。默认都是default
指定slot共享组
.map(word -> Tuple2.of(word, 1)).slotSharingGroup("aaa")
当我们将资源密集型和非密集型的任务同时放到一个slot中,他们就可以自行分配对资源占用的比例,从而保证最重的活平均分配给所有的TaskManager
slot共享的另一个好处就是允许我们保存完整的作业管道。这样一来,即使某个TaskManager出现故障宕机,其他节点也可以完全不受影响,作业的任务可以继续执行。
这样只有属于同一个slot共享组的子任务才会开启slot共享。
任务槽和并行度的关系
任务槽和并行度都跟程序的并行执行有关,但两者都是完全不同的概念。
简单来说任务槽是静态概念,是指TaskManager具有的并发执行能力,可以通过参数taskmanager.numberOfTaskSlots进行配置
而并行度是动态概念,也就是TaskManager运行程序实际使用的并发能力,可以通过参数parallelism.default进行配置
slot数量与并行度的关系
- slot是一种静态的概念,表示最大的并发上限
- 并行度是一种动态的概念,表示实际运行占了几个
- 要求:slot数量 >= job并行度(算子最大并行度),job才能运行
- 注意:yarn模式,动态申请
比如 yarn session,一开始0个TaskManager,0个slot(配置参数一个TM3个slot),现在提交一个job 并行度10 那么要开启4个TaskManager才能满足条件
也就是申请TM的数量=job并行度/每个TM的slot数量,向上取整:10/3 = 3.3 向上取整 4,使用10个slot剩余2个slot