Global Scheduler 源码分析

调度

代码中还是兼容了之前对node-heartbeat的调度方式,同时也提供了对node节点集的调度。

Global调度分为两部分,(1)确定可分配的容器(2)确认分配的容器

确定可分配的容器

在确定可分配容器的过程中,并没有实际分配容器,只是把这种可能记录下来,然后提交给Commiter。该过程大体分为三部分:

  1. 准备节点集。按照当前node的Partition获取所有属于Partition的node
  2. 自顶向下选择APP至Resource Request。与之前最大的区别是,在选择队列或者APP时,需要考虑当前队列是否可以访问当前Partition。
  3. 根据Resource Requset选择Node。首先根据Resource Request对Node进行排序,按照排序结果顺序遍历,直至找到第一个可以完成分配的Node。

确定分配容器

  1. 首先检查是否当前策略中的容器已被处理
  2. 然后从APP开始自底向上检查时候当前策略是否可行
  3. 如果可行,从APP开始自底向上进行分配容器。

Capacity Scheduler

nodeUpdate

NODE_UPDATE事件处理,只有在同步调度时,才会此处进行资源调度,就如FIFO中,默认就是同步调度。在Capacity 2.x中就可以进行异步调度,需要开启。如果要采用Global Schedule策略的话,必须异步调度,然后采用多线程,同时对多个节点集(以Partiti划分,默认是所有节点)调度。

在同步调度中,是每一次心跳调度一次,在异步调度中,与心跳无关,在函数体中allocateContainersToNode函数调用有体现。

nodeUpdate

getCandidateNodeSet

获取候选节点集。如果没有开启节点集的选项,则返回只有一个节点的节点集,还是针对单个节点进行分配;否则,获得一组同Partition的节点集。

getCandidateNodeSet

submitResourceCommitRequest

在确定可分配容器后,将分配情况提交给Commiter

submitResourceCommitRequest

tryCommit

先检查是否已被分配等,然后从APP开始,自底向上检查是否可以分配。然后从APP开始自底向上进行分配:
accept-and-apply

SchedulingMode

调度的模式,有两种,一种考虑分区排他性,一种不考虑分区排他,先进行排他调度,在进行忽略排他调度,这样可以保证优先尽可能满足APP的Partition的请求。

SchedulingMode

RESPECT_PARTITION_EXCLUSIVITY

承认分区排他性,适用于以下两种情况:

  1. 一个节点属于某个分区。只有队列中可以访问该分区的并且有向这个分区请求的APP,才会有机会在节点上分配。
  2. 一个节点没有分区。只有没有分区限制的请求的APP可以在该节点分配。

IGNORE_PARTITION_EXCLUSIVITY

忽略分区排他性,适用于以下这种情况:

一个节点属于某个分区,并且这个分区不具有分区排他性,并且只有没有分区限制的请求的APP可以在该节点分配。

ParentQueue

sortAndGetChildrenAllocationIterator

sortAndGetChildrenAllocationIterator

对儿子队列排序,不能完全按照Capacity的策略,因为使用了GLobal的分配策略,所以,要查看儿子节点是否可以访问当前的Partition。

RegularContainerAllocator

allocate

多个线程同时对一个APP操作时,做的处理如下图:

enter description here

ResourceCommitterService

在Capacity Scheduler 中实现的Commiter

ResourceCommitterService