Spark源码精读之《容器分配策略》

一、容器分配是在哪个阶段进行的?

        Spark请求Yarn的容器,不论是Client模式还是Cluster模式,都是走的相同流程。 为了简便,拿Client提交流程标识下。

        下图1,是Spark程序基于Client模式的提交总流程,容器分配就是在第4阶段, 获取Container后进行的。 

对Spark提交流程有兴趣的朋友可以浏览另一篇博文。《Spark源码精读之SparkSubmit》

二、容器分配的策略是?

        容器的分配策略有上中下三策。上策,资源请求和容器在同一个节点;中策,资源请求和容器在相同机架;下策,资源请求和容器任意位置都可。 

        程序先拿请求到的容器,逐一匹配上中下三策。匹配后,剩余用不完的容易,release掉。 然后在筛选到的容器里,启动Exectuor。

三、源码解析

def handleAllocatedContainers(allocatedContainers: Seq[Container]): Unit = {
  val containersToUse = new ArrayBuffer[Container](allocatedContainers.size)

  // Match incoming requests by host 不在同一机器上的容器
  val remainingAfterHostMatches = new ArrayBuffer[Container]
  for (allocatedContainer <- allocatedContainers) {
      matchContainerToRequest(allocatedContainer, allocatedContainer.getNodeId.getHost,containersToUse, remainingAfterHostMatches)
  }
  
  // Match remaining by rack. 不在同一节点上的容器
  val remainingAfterRackMatches = new ArrayBuffer[Container]
  for (allocatedContainer <- remainingAfterHostMatches) {
    val rack = resolver.resolve(allocatedContainer.getNodeId.getHost)
    matchContainerToRequest(allocatedContainer, rack, containersToUse,remainingAfterRackMatches)
  }
  
  // Assign remaining that are neither node-local nor rack-local 将被Release的容器
  val remainingAfterOffRackMatches = new ArrayBuffer[Container]
  for (allocatedContainer <- remainingAfterRackMatches) {
    matchContainerToRequest(allocatedContainer, ANY_HOST, containersToUse,remainingAfterOffRackMatches)
  }
  // 没有用到的容器,release掉。
  if (remainingAfterOffRackMatches.nonEmpty) {
    for (container <- remainingAfterOffRackMatches) {
    internalReleaseContainer(container)
    }
  }
  // 启动容器
  runAllocatedContainers(containersToUse)
}
/**
 * Looks for requests for the given location that match the given container allocation. If it finds one, removes the request so that it won't be submitted again. Places the container into containersToUse or remaining. 查找与给定容器分配匹配的给定位置的请求。如果它找到一个,则删除该请求,这样它就不会再次提交。将容器放入要使用或剩余的容器中。
 * @param allocatedContainer container that was given to us by YARN YARN给的容器中的一个
 * @param location resource name, either a node, rack, or *   资源名称 node、rack或者其他
 * @param containersToUse list of containers that will be used 将被使用的容器列表
 * @param remaining list of containers that will not be used 没被使用的剩余容器
 */
// 这个函数,用于把YARN请求返回的容器和位置进行匹配,匹配成功放入containersToUse参数,否则放入remaining参数。
private def matchContainerToRequest(
    allocatedContainer: Container,
    location: String,
    containersToUse: ArrayBuffer[Container],
    remaining: ArrayBuffer[Container]): Unit = {
    ......
    val matchingRequests = amClient.getMatchingRequests(allocatedContainer.getPriority, location,matchingResource)
    if (!matchingRequests.isEmpty) {
    //若yarn给的容器,和
        val containerRequest = matchingRequests.get(0).iterator.next
        amClient.removeContainerRequest(containerRequest)
        containersToUse += allocatedContainer
    } else {
        remaining += allocatedContainer
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值