何为Slot
本质上是存在于TaskManage JVM进程中的线程。每个Slot可以装配多个subtask。TaskManager启动时可以设置固定数量的Slot,
官网示意图
为何要有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。
基于这个原理,诞生了一个调优思路。有些subtask需要很大的计算能力如Window聚合计算。默认它会和其他subtask共享在一个Slot也就是一个线程内。可以手动控制这种重型subtask独享一个Slot。进行调优。
人为调控Slot共享方法
主要两大机制:SlotSharingGroup、CoLocationGroup。
SlotSharingGroup
默认情况下,会把编号相同的subtask放在一个Slot中,如上面示意图中的编号。这是因为所有subtask的SlotSharingGroup为default。。所以想要某些subtask不和其余共享slot,想要单拿出来放入一个Slot,只需要改变SlotSharingGroup即可。
代码实例如下。map算子设置成新的组,同组同编号会尽可能放在一个Slot。
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之间,是序列化反序列化。