何为Slot

本质上是存在于TaskManage JVM进程中的线程。每个Slot可以装配多个subtask。TaskManager启动时可以设置固定数量的Slot,

官网示意图

image.png

为何要有Slot

Slot用于均分TaskManager的内存资源,TM上的Slot共享CPU资源。也就是Slot只是对内存资源进行了隔离,没有对CPU进行隔离。Slot的数量决定了一个TM为Job的subtask提供多少个并发线程。
对TaskManager中的内存资源进行切分隔离。使位于不同Slot的subtask之间在内存层面互不影响。保证集群中多Job的良好运行。
并且用户可以根据有限的计算资源自定义划分每个TM的Slot数,进行性能调优。

共享Slot

默认情况下,同一个Job中不同task的subtask尽可能共享一个Slot。这就得出一个结论,并行度和所需的Slot相等。默认情况下,Flink会尽可能压榨单个Slot。放入尽可能多的subtask。这样做的目的使Slot之前负载尽可能均衡,并减少Slot间网络传输,提高性能。

官方示意图

最左左边Slot拥有一个完整的pipeline。
image.png

基于这个原理,诞生了一个调优思路。有些subtask需要很大的计算能力如Window聚合计算。默认它会和其他subtask共享在一个Slot也就是一个线程内。可以手动控制这种重型subtask独享一个Slot。进行调优。

人为调控Slot共享方法

主要两大机制:SlotSharingGroup、CoLocationGroup。

SlotSharingGroup

默认情况下,会把编号相同的subtask放在一个Slot中,如上面示意图中的编号。这是因为所有subtask的SlotSharingGroup为default。。所以想要某些subtask不和其余共享slot,想要单拿出来放入一个Slot,只需要改变SlotSharingGroup即可。
代码实例如下。map算子设置成新的组,同组同编号会尽可能放在一个Slot。

  1. dataStream.map.slotSharingGroup("foo-group");

关闭整个Job的Chain
StreamExecutionEnvironment.disableOperatorChaining()

关闭Operator之间拷贝。
ExecutionConfig.enableObjectReuse()

CoLocationGroup

SharedSlot和SimpleSlot

没有ColocationConstraint都分配SimpleSlot
如果有ColocationConstraint就在SharedSlot下分配一个SharedSlot

SlotSharingGroupAssignment类管理SharedSlot

数据传递

subtask内部operator之间默认是深拷贝。
Slot内部subtask之间,是序列化反序列化。