Skip to content
gqlxj1987's Blog
Go back

Yarn Schedule

Edit page

原文链接

FairScheduler/CapacityScheduler

采用层级树的方式,FairScheduler通过这样一棵资源树,维护了整个集群的资源使用情况。资源树中的每一个叶子节点都挂载了此时正在这个队列上运行、或者正在申请运行的应用。FairScheduler只需要对这个树进行适当遍历,就可以知道任何一个资源队列当前有哪些应用在运行、队列当前还剩下多少资源、已经使用多少资源等

###心跳调度

NM通过心跳的方式定期向RM汇报自身状态,

###持续调度

不用等待NodeManager向ResourceManager发送心跳才进行任务调度,而是由一个独立的线程进行实时的资源分配等调度,与NodeManager的心跳出发的调度相互异步并行进行。当心跳到来,只需要把调度结果通过心跳响应告诉对应的NodeManager即可

两种触发机制不同的地方只有两个:

调度时机:心跳调度仅仅发生在收到了某个NodeManager的心跳信息的情况下,持续调度则不依赖与NodeManager的心跳通信,是连续发生的,当心跳到来,会将调度结果直接返回给NodeManager;

调度范围:心跳调度下,当收到某个节点的心跳,就对这个节点且仅仅对这个节点进行一次调度。持续调度的每一轮,是会遍历当前集群的所有节点,每个节点依次进行一次调度,保证一轮下来每个节点都被公平的调度一次

void continuousSchedulingAttempt() throws InterruptedException {
  long start = getClock().getTime();
  List<NodeId> nodeIdList = new ArrayList<NodeId>(nodes.keySet());
  //进行调度以前,先对节点根据剩余资源的多少进行排序,从而让资源更充裕的节点先得到调度
  //这样我们更容易让所有节点的资源能够被均匀分配,而不会因为某些节点总是先被调度所以总是比
  //后调度的节点的资源使用率更高
  synchronized (this) {
    Collections.sort(nodeIdList, nodeAvailableResourceComparator);
  }
  // 遍历所有节点,依次对每一个节点进行一次调度
  for (NodeId nodeId : nodeIdList) {
    //FSSchedulerNode是FairScheduler视角下的一个节点
    FSSchedulerNode node = getFSSchedulerNode(nodeId);
    try {
      //判断
      if (node != null && Resources.fitsIn(minimumAllocation,
          node.getAvailableResource())) {
        attemptScheduling(node);
      }
    } catch (Throwable ex) { //这每次调度过程中如果发生异常,这个异常将被捕获,因此不会影响在其它节点上进行调度
      //异常处理,略
      }
    }
  }

  long duration = getClock().getTime() - start;
  fsOpDurations.addContinuousSchedulingRunDuration(duration);
}

比较器部分,实际上只是比较了内存

预留资源同非预留资源的区别对待

剥离预留/尝试分配资源

适合在这个节点运行

public enum NodeType {
    NODE_LOCAL(0), //请求规定了必须运行在某个的服务器节点
    RACK_LOCAL(1), //请求规定了必须运行在某个机架上
    OFF_SWITCH(2); //这个请求对本地化没有要求
    public int index;

    private NodeType(int index) {
      this.index = index;
    }
}

Edit page
Share this post on:

Previous Post
Executors同Thread Groups
Next Post
没钱的31岁