yarn实现

YARN基础库

YARN的基础库主要有以下几个。
❑Protocol Buffers:Protocol Buffers是Google开源的序列化库,具有平台无关、高性能、兼容性好等优点。
❑Apache Avro:Avro是Hadoop生态系统中的RPC框架,具有平台无关、支持动态模式(无需编译)等优点。
❑RPC库:YARN仍采用了MRv1中的RPC库,但其中采用的默认序列化方法被替换成了Protocol Buffers。
❑服务库和事件库:YARN将所有的对象服务化,以便统一管理(比创建、销毁等),而服务之间则采用事件机制进行通信,不再使用类似MRv1中基于函数调用的方式。
❑状态机库:状态机是一种表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。在YARN中,很多对象都是由若干状态组成的,且当有事件发生时,状态之间会发生转移。
hadoop rpc
HadoopRPC的主要类关系图
HadoopRPC中服务器端动态代理实现类图
Client类图
Hadoop RPC Server处理流程
服务库
YARN中服务模型的类图
事件库
YARN的事件处理模型
事件与事件处理器
状态机库
状态机类图

ApplicationMaster设计

AM-RM编写流程
ApplicationMaster与ResourceManager通信流程
步骤1 ApplicationMaster通过RPC函数ApplicationMasterProtocol#registerApplicationMaster向ResourceManager注册。
步骤2 ApplicationMaster通过RPC函数ApplicationMasterProtocol#allocate向Resource-Manager申请资源(以Container形式表示)。
步骤3 ApplicationMaster通过RPC函数ApplicationMasterProtocol#finishApplicationMaster告诉ResourceManager应用程序执行完毕,并退出。
AM-NM编写流程
ApplicationMaster与NodeManager通信流程
步骤1 ApplicationMaster将申请到的资源二次分配给内部的任务,并通过RPC函数ContainerManagementProtocol#startContainer与对应的NodeManager通信以启动Container(包含任务描述、资源描述等信息),该函数的参数类型为StartContainersRequest,主要包含一个类型为StartContainersRequest的字段,它自身包含以下两个字段(字段名称使用了Protocol Buffers文件中定义的名称)。
步骤2 为了实时掌握各个Container运行状态,ApplicationMaster可通过RPC函数ContainerManagementProtocol#getContainerStatus向NodeManager询问Container运行状态,一旦发现某个Container运行失败,ApplicationMaster可尝试重新为对应的任务申请资源。
步骤3 一旦一个Container运行完成后,ApplicationMaster可通过RPC函数ContainerManagementProtocol#stopContainer释放Container。注意,YARN是一个资源管理系统,它不仅负责分配资源,还负责回收资源。当一个Container运行完成后,它会主动确认Container是否将对应的资源释放了,也就是说,任何一个Container运行结束后(此时Container可能已经退出且释放资源),ApplicationMaster必须调用RPC函数ContainerManagementProtocol#stopContainer释放Container(确保资源真的得到释放)。

ResourceManager 剖析

ResourceManager基本职能
❑ResourceTracker:NodeManager通过该RPC协议向ResourceManager注册、汇报节点健康状况和Container运行状态,并领取ResourceManager下达的命令,这些命令包括重新初始化、清理Container等,在该RPC协议中,ResourceManager扮演RPC Server的角色(由内部组件ResourceTrackerService实现),而NodeManager扮演RPC Client的角色,换句话说,NodeManager与ResourceManager之间采用了“pull模型”(与MRv1类似),NodeManager 总是周期性地主动向ResourceManager发起请求,并通过领取下达给自己的命令。
❑ApplicationMasterProtocol:应用程序的ApplicationMaster通过该RPC协议向ResourceManager注册、申请资源和释放资源。
❑ApplicationClientProtocol:应用程序的客户端通过该RPC协议向ResourceManager提交应用程序、查询应用程序状态和控制应用程序(比如杀死应用程序)等。
ResourceManager相关的RPC协议
ResourceManager内部架构
ResourceManager主要由以下几个部分组成:
❑用户交互模块。ResourceManager分别针对普通用户、管理员和Web提供了三种对外服务,具体实现分别对应ClientRMService、AdminService和WebApp。
 ❍ClientRMService。ClientRMService是为普通用户提供的服务,它处理来自客户端各种RPC请求,比如提交应用程序、终止应用程序、获取应用程序运行状态等。
 ❍AdminService。ResourceManager为管理员提供了一套独立的服务接口,以防止大量的普通用户请求使管理员发送的管理命令饿死,管理员可通过这些接口管理集群,比如动态更新节点列表、更新ACL列表、更新队列信息等。
 ❍WebApp。为了更加友好地展示集群资源使用情况和应用程序运行状态等信息,YARN对外提供了一个Web 界面,这一部分是YARN仿照Haml[插图]开发的一个轻量级嵌入式Web框架[插图]。
❑NM管理模块。该模块主要涉及以下组件:
❍NMLivelinessMonitor。监控NM是否活着,如果一个NodeManager在一定时间(默认为10min)内未汇报心跳信息,则认为它死掉了,需将其从集群中移除。
 ❍NodesListManager。维护正常节点和异常节点列表,管理exclude(类似于黑名单)和include(类似于白名单)节点列表,这两个列表均是在配置文件中设置的,可以动态加载。 
 ❍ResourceTrackerService。处理来自NodeManager的请求,主要包括注册和心跳两种请求,其中,注册是NodeManager启动时发生的行为,请求包中包含节点ID、可用的资源上限等信息;而心跳是周期性行为,包含各个Container运行状态,运行的Application列表、节点健康状况(可通过一个脚本设置)等信息,作为请求的应答,ResourceTrackerService可为NodeManager返回待释放的Container列表、Application列表等信息。
❑AM管理模块。该模块主要涉及以下组件: 
❍AMLivelinessMonitor。监控AM是否活着,如果一个ApplicationMaster在一定时间(默认为10min)内未汇报心跳信息,则认为它死掉了,它上面所有正在运行的Container将被置为失败状态,而AM本身会被重新分配到另外一个节点上(用户可指定每个ApplicationMaster的尝试次数,默认是2)执行。
 ❍ApplicationMasterLauncher。与某个NodeManager通信,要求它为某个应用程序启动ApplicationMaster。 
 ❍ApplicationMasterService(AMS)。处理来自ApplicationMaster的请求,主要包括注册和心跳两种请求。
❑Application管理模块。该模块主要涉及以下组件:
 ❍ApplicationACLsManage。管理应用程序访问权限,包含两部分权限:查看权限和修改权限。查看权限主要用于查看应用程序基本信息,而修改权限则主要用于修改应用程序优先级、杀死应用程序等。
 ❍RMAppManager。管理应用程序的启动和关闭。 
 ❍ContainerAllocationExpirer。当AM收到RM新分配的一个Container后,必须在一定的时间(默认为10min)内在对应的NM上启动该Container,否则RM将强制回收该Container,而一个已经分配的Container是否该被回收则是由ContainerAllocationExpirer决定和执行的。
❑状态机管理模块。ResourceManager使用有限状态机维护有状态对象的生命周期,正如第3章所介绍的,状态机的引入使得YARN设计架构更加清晰。ResourceManager共维护了4类状态机,分别是RMApp、RMAppAttempt、RMContainer和RMNode(这几个均是接口,具体实现类为对应接口名加上"Impl"后缀)。 
❍RMApp。RMApp维护了一个应用程序(Application)的整个运行周期,包括从启动到运行结束整个过程。由于一个Application的生命周期可能会启动多个Application运行实例(Application Attempt),因此可认为,RMApp维护的是同一个Application启动的所有运行实例的生命周期。
 ❍RMAppAttempt。一个应用程序可能启动多个实例,即一个实例运行失败后,可能再次启动一个重新运行,而每次启动称为一次运行尝试(或者“运行实例”),用"RMAppAttempt"描述,RMAppAttempt维护了一次运行尝试的整个生命周期。 
 ❍RMContainer。RMContainer维护了一个Container的运行周期,包括从创建到运行结束整个过程。ResourceManager将资源封装成Container发送给应用程序的ApplicationMaster,而ApplicationMaster则会在Container描述的运行环境中启动任务,因此,从这个层面上讲,Container和任务的生命周期是一致的(目前YARN尚不支持Container重用,一个Container用完后会立刻释放,将来可能会增加Container重用机制)。 
 ❍RMNode。RMNode维护了一个NodeManager的生命周期,包括启动到运行结束整个过程。
❑安全管理模块。ResourceManage自带了非常全面的权限管理机制,主要由ClientTo-AMSecretManager、ContainerTokenSecretManager、ApplicationTokenSecretManager等模块完成。
❑资源分配模块。该模块主要涉及一个组件—ResourceScheduler。ResourceScheduler是资源调度器。
ResourceManager内部架构图
ResourceManager事件与事件处理器
NodeManager内部事件与事件处理器
ResourceManager内部事件与事件处理器交互图
ApplicationMaster管理
ApplictionMaster管理部分主要由三个服务构成,分别是ApplicationMasterLauncher、AMLivelinessMonitor和ApplicationMasterService,它们共同管理应用程序的Application-Master的生存周期。
步骤1 用户向YARN ResourceManager提交应用程序,ResourceManager收到提交请求后,先向资源调度器申请用以启动ApplicationMaster的资源,待申请到资源后,再由ApplicationMasterLauncher与对应的NodeManager通信,从而启动应用程序的ApplicationMaster。
ApplicationMaster启动流程
步骤2 ApplicationMaster启动完成后,ApplicationMasterLauncher会通过事件的形式,将刚刚启动的ApplicationMaster注册到AMLivelinessMonitor,以启动心跳监控。
步骤3 ApplicationMaster启动后,先向ApplicationMasterService注册,并将自己所在host、端口号等信息汇报给它。
步骤4 ApplicationMaster运行过程中,周期性地向ApplicationMasterService汇报“心跳”信息(“心跳”信息中包含想要申请的资源描述)。
步骤5 ApplicationMasterService每次收到ApplicationMaster的心跳信息后,将通知AMLivelinessMonitor更新该应用程序的最近汇报心跳的时间。
步骤6 当应用程序运行完成后,ApplicationMaster向ApplicationMasterService发送请求,注销自己。步骤7 ApplicationMasterService收到注销请求后,标注应用程序运行状态为完成,同时通知AMLivelinessMonitor移除对它的心跳监控。
NodeManager管理
NodeManager管理部分主要由三个服务构成,分别是NMLivelinessMonitor、Nodes-ListManager和ResourceTrackerService,它们共同管理NodeManager的生存周期,接下来我们依次介绍这三个服务。
(1)NMLivelinessMonitor该服务周期性遍历集群中所有NodeManager,如果一个NodeManager在一定时间(可通过参数yarn.nm.liveness-monitor.expiry-interval-ms配置,默认为10min)内未汇报心跳信息,则认为它死掉了,它上面所有正在运行的Container将被置为运行失败。需要注意的是,RM不会重新执行这些Container,它只会通过心跳机制告诉对应的AM,由AM决定是否重新执行。
(2)NodesListManager
NodesListManager管理exlude(类似于黑名单)和inlude(类似于白名单)节点列表,这两个列表所在的文件分别可通过yarn.resourcemanager.nodes.include-path和yarn.resourcemanager.nodes.exclude-path配置(每个节点的host或者IP占一行),其中,exlude节点列表可认为是黑名单,它们不允许直接与RM通信(直接在RPC层抛出异常,导致NM退出),而inlude节点列表可认为是白名单(通常不将这两个名单直接称为黑名单和白名单,这两个概念被用到了YARN其他地方)。
(3)ResourceTrackerService
ResourceTrackerService实现了RPC协议ResourceTracker,负责处理来自各个NodeManager的请求,请求主要包括注册和心跳两种,其中,注册是NodeManager启动时发生的行为,请求包中包含节点ID,可用的资源上限等信息;而心跳是周期性行为,包含各个Container运行状态,运行的Application列表、节点健康状况(可通过一个脚本设置,具体阅读第7章),而ResourceTrackerService则为NM返回待释放的Container列表、Application列表等。
Application管理
(1)ApplicationACLsManager
ApplicationACLsManager负责管理应用程序的访问权限,包含两部分权限:查看权限和修改权限。
(2)RMAppManager
RMAppManager负责应用程序的启动和关闭。
(3)ContainerAllocationExpirer
当一个AM获得一个Container后,YARN不允许AM长时间不对其使用,因为这会降低整个集群的利用率。当AM收到RM新分配的一个Container后,必须在一定的时间(默认为10min,管理员可通过参数yarn.resourcemanager.rm.container-allocation.expiry-interval-ms修改)内在对应的NM上启动该Container,否则RM将强制回收该Container。

资源调度器

YARN资源调度器是直接从MRv1基础上修改而来的,它提供了三种可用资源调度器,分别是FIFO(First In First Out)、Yahoo!的Capacity Scheduler和Facebook的Fair Scheduler,它们的实现原理和实现细节与MRv1中对应的三种调度器基本一致。
所有的资源调度器均应该实现接口org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler,该接口的定义如下:

public interface ResourceScheduler extends YarnScheduler, Recoverable {
  // 重新初始化ResourceScheduler,通常在ResourceManager初始化时调用
  //(包括主备ResourceManager切换)
  void reinitialize(Configuration conf, RMContext rmContext) throws IOException;
}

其中,接口YarnScheduler的定义如下:

public interface YarnScheduler extends EventHandler<SchedulerEvent> {
  // 获取一个队列的基本信息,queueName为队列名称,includeChildQueues表示是否包
  // 含子队列,recursive表示是否递归返回其子队列的信息
  public QueueInfo getQueueInfo(String queueName, boolean includeChildQueues,
      boolean recursive) throws IOException;
  // 返回当前用户的队列ACL权限
  public List<QueueUserACLInfo> getQueueUserAclInfo();
  // 返回调度器最少可分配的资源
  public Resource getMinimumResourceCapability();
  // 返回调度器最多可分配的资源
  public Resource getMaximumResourceCapability();
  //返回当前集群中可用节点的总数
  public int getNumClusterNodes();
// ApplicationMaster和资源调度器之间最主要的API,ApplicationMaster通过该API更新
// 资源需求和待释放的Container列表,其中appAttemptId为应用程序实例ID,ask为新
// 请求资源的描述,release为待释放Container列表,blacklistAdditions为待加入黑名单
// 的节点列表,blacklistRemovals为待移除黑名单的节点列表
  Allocation
  allocate(ApplicationAttemptId appAttemptId,
      List<ResourceRequest> ask,
      List<ContainerId> release,
      List<String> blacklistAdditions,
      List<String> blacklistRemovals);
  // 获取节点资源使用情况报告
  public SchedulerNodeReport getNodeReport(NodeId nodeId);
  // 获取运行实例appAttemptId的SchedulerAppReport对象
  SchedulerAppReport getSchedulerAppInfo(ApplicationAttemptId appAttemptId);
  // 获取root队列的Metric信息
  QueueMetrics getRootQueueMetrics();
}

接口Recoverable的定义如下:

public interface Recoverable {
  // ResourceManager重启后将调用该函数恢复调度器内部的信息
  public void recover(RMState state) throws Exception;
}

资源调度器基本架构
(1)支持的调度语义
当前YARN支持的调度语义包括:
❑请求某个特定节点上的特定资源量。比如,请求节点nodeX上5个这样的Container:虚拟CPU个数为2,内存量为2GB。
❑请求某个特定机架上的特定资源量。比如,请求机架rackX上3个这样的Container:虚拟CPU个数为4,内存量为3GB。
❑将某些节点加入(或移除)黑名单,不再为自己分配这些节点上的资源。比如,ApplicationMaster发现节点nodeX和nodeY失败的任务数目过多,可请求将这两个节点加入黑名单,从而不再收到这两个节点上的资源,过一段时间后,可请求将nodeX移除黑名单,从而可再次使用该节点上的资源。
❑请求归还某些资源。比如,ApplicationMaster已获取的来自节点nodeX上的2个Container暂时不用了,可将之归还给集群,这样这些资源可再次分配给其他应用程序。
(2)不支持的调度语义当前不支持的调度语义包括:
❑请求任意节点上的特定资源量。比如,请求任意节点上5个这样的Container:虚拟CPU个数为3,内存量为1GB。
❑请求任意机架上的特定资源量。比如,请求同一个机架上(具体哪个机架并不关心,但是必须来自同一个机架)3个这样的Container:虚拟CPU个数为1,内存量为6GB。
❑请求一组或几组符合某种特质的资源。比如,请求来自两个机架上的4个Container,其中,一个机架上2个这样的Container:虚拟CPU个数为2,内存量为2GB;另一个机架上2个这样的资源:虚拟CPU个数为2,内存量为3GB。如果目前集群没有这样的资源,需要从其他应用程序处抢占资源。
❑超细粒度资源。比如CPU性能要求、绑定CPU等。
❑动态调整Container资源,应允许根据需要动态调整Container资源量(对于长作业尤其有用)。
在YARN中,资源分配过程可概括为以下7个步骤:
步骤1 NodeManager通过周期性心跳汇报节点信息。
步骤2 ResourceManager为NodeManager返回一个心跳应答,包括需释放的Container列表等信息。
步骤3 ResourceManager收到来自NodeManager的信息后,会触发一个NODE_UPDATE事件。
步骤4 ResourceScheduler收到NODE_UPDATE事件后,会按照一定的策略将该节点上的资源(步骤2中有释放的资源)分配各应用程序,并将分配结果放到一个内存数据结构中。
步骤5 应用程序的ApplicationMaster向ResourceManager发送周期性的心跳,以领取最新分配的Container。
步骤6 ResourceManager收到来自ApplicationMaster心跳信息后,为它分配的container将以心跳应答的形式返回给ApplicationMaster。
步骤7 ApplicationMaster收到新分配的container列表后,会将这些Container进一步分配给它内部的各个任务。
资源保证机制
在分布式计算中,资源调度器需选择合适的资源保证这样的机制:当应用程序申请的资源暂时无法保证时,是优先为应用程序预留一个节点上的资源直到累计释放的空闲资源满足应用程序需求(称为“增量资源分配”,即Incremental placement),还是暂时放弃当前资源直到出现一个节点剩余资源一次性满足应用程序需求(称为“一次性资源分配”,all-or-nothing)。这两种机制均存在优缺点,对于增量资源分配而言,资源预留会导致资源浪费,降低集群资源利用率;而一次性资源分配则会产生饿死现象,即应用程序可能永远等不到满足资源需求的节点出现。
YARN采用了增量资源分配机制,尽管这种机制会造成浪费。
资源分配算法
为了支持多维资源调度,YARN资源调度器采用了主资源公平调度算法(Dominant Resource Fairness,DRF)[插图],该算法扩展了最大最小公平(max-min fairness)算法[插图],使其能够支持多维资源的调度。
在DRF算法中,将所需份额(资源比例)最大的资源称为主资源,而DRF的基本设计思想则是将最大最小公平算法应用于主资源上,进而将多维资源调度问题转化为单资源调度问题,即DRF总是最大化所有主资源中最小的,其算法伪代码如下:

function void DRFScheduler()
  R ← <r1,, rm>;   //m种资源对应的容量
  C ← <c1,, cm>;  //已用掉的资源,初始值为 0
  si (i = 1..n);  //用户(或者框架)i的主资源所需份额,初始化为0
  Ui← <ui,1,, ui,m> (i = 1..n)  // 分配给用户i的资源,初始化为0
  挑选出主资源所需份额si最小的用户i;
  Di ← {用户i的下一个任务需要的资源量}if C + Di <= R then
    //将资源分配给用户i
    C ← C + Di; //更新C
    Ui ← Ui + Di; //更新U
    si = maxmj=1{ui,j/rj};
  else
    return; //资源全部用完
  end if
end function

下面我们看一个实例。假设系统中共有9个CPU和18GB RAM,有两个用户(或者框架)分别运行了两种任务,需要的资源量分别为<1CPU,4GB>和<3CPU,1GB>。对于用户A,每个任务要消耗总CPU的1/9(份额)和总内存的2/9,因而A的主资源为内存;对于用户B,每个任务要消耗总CPU的1/3和总内存的1/18,因而B的主资源为CPU。DRF将最大化所有用户的主资源,具体分配过程如表6-1所示。最终,A获取的资源量为<3CPU,12GB>,可运行3个任务;而B获取的资源量为<6CPU,2GB>,可运行2个任务。
DRF算法的调度序列
资源抢占模型
在资源调度器中,每个队列可设置一个最小资源量和最大资源量,其中,最小资源量是资源紧缺情况下每个队列需保证的资源量,而最大资源量则是极端情况下队列也不能超过的资源使用量。
资源调度器(包括Capacity Scheduler和Fair Scheduler)会将负载较轻的队列的资源暂时分配给负载重的队列(即最小资源量并不是硬资源保证,当队列不需要任何资源时,并不会满足它的最小资源量,而是暂时将空闲资源分配给其他需要资源的队列),仅当负载较轻队列突然收到新提交的应用程序时,调度器才进一步将本属于该队列的资源分配给它。但由于此时资源可能正被其他队列使用,因此调度器必须等待其他队列释放资源后,才能将这些资源“物归原主”,这通常需要一段不确定的等待时间。
下面我们举例说明。如图6-5所示,整个集群资源总量为100(为了简便,没有区分CPU或者内存),且被分为三个队列,分别是QueueA、QueueB和QueueC。它们的最小资源量和最大资源量(由管理员配置)分别是(10,15)、(20,35)和(60,65)。某一时刻,它们尚需的资源量和正在使用的资源量分别是(0,5)、(10,30)和(60,65),即队列QueueA负载较轻,部分资源暂时不会使用,它将不会使用的5个资源共享给了其他两个队列(QueueB和QueueC分别得到2个和3个),而队列QueueB和QueueC除了使用来自队列QueueA的资源外,还使用了整个系统共享的10个资源(100–10–20–60=10)。某一时刻,队列QueueA突然增加了一批应用程序,此时共需要20个资源,则资源调度器需要从QueueB和QueueC中抢占5个本该属于QueueA的资源。需要注意的是,为了避免资源浪费,资源调度器通常会等待一段时间后才会强制回收资源,而在这段等待时间内,QueueB和QueueC可能已经释放了本该属于QueueA的资源。
仅当启用的调度器实现了PreemptableResourceScheduler接口,且参数yarn.resourcemanager.scheduler.monitor.enable的值被置为true(默认值为false)时,ResourceManager才启用资源抢占功能。
资源抢占发生时机
在YARN中,资源抢占整个过程可概括为如下步骤:
步骤1 SchedulingEditPolicy探测到需要抢占的资源,将需要抢占的资源通过事件DROP_RESERVATION和PREEMPT_CONTAINER发送给ResourceManager。
步骤2 ResourceManager调用ResourceScheduler的dropContainerReservation和preempt-Container函数,标注待抢占的Container。
步骤3 ResourceManager收到来自ApplicationMaster的心跳信息,并通过心跳应答将待释放的资源总量和待抢占Container列表发返回给它。ApplicationMaster收到该列表后,可选择如下操作:
1)杀死这些Container。
2)选择并杀死其他Container以凑够总量。
3)不做任务处理,过段时间可能有Container自行释放资源或者由ResourceManager杀死Container。
步骤4 SchedulingEditPolicy探测到一段时间内,ApplicationMaster未自行杀死约定的Container,则将这些Container封装到KILL_CONTAINER事件中发送给ResourceManager。
步骤5 ResourceManager调用ResourceScheduler的killContainer函数,而Resource-Scheduler则标注这些待杀死的Container。
步骤6 ResourceManager收到来自NodeManager的心跳信息,并通过心跳应答将待杀死的Container列表返回给它,NodeManager收到该列表后,将这些Container杀死,并通过心跳告知ResourceManager。
步骤7 ResourceManager收到来自ApplicationMaster的心跳信息,并通过心跳应答将已经杀死的Container列表发送给它(可能ApplicationMaster早已通过内部通信机制知道了这些被杀死的Container)。
资源抢占流程
问题1:如何决定是否抢占某个队列的资源?
在YARN中,队列是按照树形结构组织的,一个队列当前实际可以使用的资源量R取决于最小资源量A(由管理员配置)、队列资源需求量B(处于等待或者运行状态的应用程序尚需的资源总量)和同父兄弟队列的空闲资源量C(多余资源可共享给其他队列),这意味着R在不同时间点的取值是不同的,可以按照递归算法求出R=F(A,B,C),这样,如果一个队列当前正在使用资源量U>R,则需从该队列中抢占(U–R)资源。
为了方便读者理解以上算法,下面给出一个实例。
如图6-7所示,整个集群资源总量为100(为了简便,没有区分CPU或者内存),且被划分为三个队列,分别是QueueA、QueueB和QueueC,它们的最小资源量(由管理员配置)分别是24、16和40,在t1时刻,它们尚需的资源量和正在使用的资源量分别是(0,20)、(0,20)和(80,60),则按照computeIdealResourceDistribution函数计算,第一轮可得到如表6-2所示的结果。
资源抢占资源量计算方法
t1时刻第一轮计算结果
经过第一轮计算、wQassigned=90,unassigned=10。
第二轮计算结果如表6-3所示。
t1时刻第二轮计算结果
经过第二轮计算:wQassigned=95,unassigned=5。由于QueueA和QueueB的wQdone为0,不再进入下一轮计算。
第三轮计算结果如表6-4所示。
t1时刻第三轮计算结果
经过这一轮计算:unassigned=0,所有资源分配完成,退出计算。这样三个队列真正可以使用的资源为20、20和60,很显然,它们当前正在使用的资源均未超过这三个值,所以不会发生任何资源抢占。
假设t2时刻,用户向QueueA提交了一批应用程序,使得资源需求量由0变为100,其他状态不变。按照computeIdealResourceDistribution函数计算,第一轮可得到的结果如表6-5所示。
t2时刻第一轮计算结果
经过第一轮计算:wQassigned=100,unassigned=0,所有资源分配完成,退出计算。由于QueueC当前正在使用的资源量为60,超过了应得的资源量50,需要从它里面抢占10个资源。
问题2:如何使资源抢占代价最小?
YARN优先选择优先级低的Container作为资源抢占对象,且不会立刻杀死Container,而是将释放资源的任务留给应用程序自己:ResourceManager将待杀死的Container列表发送给对应的ApplicationMaster,以期望它采取一定的机制自行释放这些Container占用的资源,比如先进行一些状态保存工作后,再将对应的Container杀死,以避免计算浪费,如果一段时间后,ApplicationMaster尚未主动杀死这些Container,则ResourceManager再强制杀死这些Container。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值