[toc]
【知乎】Presto 是如何 schedule task 的?
presto查询处理流程-queryexecution提交
presto内部4种计算类型的节点#
-
source节点,读源数据的节点,负责读取数据、Map阶段的计算任务。分配的个数由SplitManager根据数据决定。
-
fixed节点,shuffle节点,用于处理reduce任务。比如group by计算,source阶段的数据按照hash发送到fixed节点。分配的个数由3. hash_partition_count这个session参数决定,由于是固定个数,所以对于不同的数据规模采用同样的个数也不是很合适,这也是需要改进的点。
-
single节点,单节点计算任务,某些计算需要在单一节点计算,比如MergeReduce,output等,需要分配一个节点。
-
coordinator only,只在coordinator节点计算的任务,一般是meta类操作。
preosto种的split是什么?
【CSDN】presto-spilt详解
Source Stage调度过程#
由SectionExecutionFactory.createStageScheduler我们可以知道
具体的节点分配split策略的实现类为DynamicSplitPlacementPolicy。跟踪其调用栈可以发现,其具体实现为TopologyAwareNodeSelector.computeAssignments方法,其主要流程如下:
- 将所有活跃的工作节点作为候选节点;
- 如果分片的节点选择策略是HARD_AFFINITY,即分片只能在特定节点进行访问,则根据分片要求更新候选节点列表;
- 如果分片的节点选择策略不是HARD_AFFINITY,则根据节点的网络拓扑,从候选节点中选择和分片偏好节点网络路径最匹配的节点列表来更新候选节点列表;最重要目的是让source节点尽可能靠近数据源
- 使用bestNodeSplitCount方法从更新后的候选节点列表中选择最合适的节点来分配分片;
从候选节点列表中选择最优节点的算法TopologyAwareNodeSelector.bestNodeSplitCount的流程如下:
- 从候选节点列表中随机选择一个(传入节点列表时已进行随机打散new ResettableRandomizedIterator<>(nodes)),如果该节点已分配的Split尚未达到阈值,则选择该节点;
- 如果第1步选择的节点已分配Split达到上限,则选择剩余节点中在当前stage中排队Split最少的节点。
signle和fixed调度过程#
选择FixedCountScheduler策略
可以看到FixedCountScheduler只是在nodePartitionMap.getPartitionToNode返回的固定节点列表上调度任务,在选定的每个节点上相应创建一个任务。
Single和Fixed Stage的节点选择比较简单,均为随机性选择,且调用方法为同一个:NodeSelector.selectRandomNodes。
Single Stage只会随机地从所有存活节点列表中选择一个节点,Fixed Stage会随机选择参数hash_partition_count和max_tasks_per_stage两者的小值数量的节点。
Presto的查询调度本质上就是Split分配到各个节点的过程,每个阶段依据本身所承担的职责,调度方式有所区别,从整体上来说,Split分配节点的方式基本为随机选择的策略,在此基础上尽量保证每个节点处理的Split相对平均。