我们首先简要介绍机会容器,包括用户如何启用此功能以及使用此类容器运行示例作业。
与仅在有未分配资源的情况下在节点中调度的现有YARN容器不同,机会容器可以调度到NM,即使它们无法在该节点上立即执行。在这种情况下,机会容器将在该NM排队,直到资源可用为止。机会容器执行的主要目标是提高群集资源利用率,从而提高任务吞吐量。对于包括相对较短的任务(以秒为单位)的工作负载,资源利用率和任务吞吐量的改善更为明显。
要启用机会容器分配,conf / yarn-site.xml中必须存在以下两个属性:
属性 | 描述 | 默认值 |
---|---|---|
启用yarn.resourcemanager.opportunistic-container-allocation | 启用机会容器分配。 | 假 |
yarn.nodemanager。机会容器最大队列长度 | 确定可以在NM上排队的机会容器的最大数量。 | 0 |
上面的第一个参数必须设置为true。第二个值必须设置为正值,以允许在NM处对机会容器进行排队。值10可用于开始尝试机会容器。最佳值取决于作业特征,群集配置和目标利用率。
默认情况下,机会容器的分配是通过RM集中执行的。但是,用户可以选择启用机会容器的分布式分配,这可以进一步改善短期任务的分配延迟。可以通过将以下参数设置为true来启用分布式调度(请注意,非机会容器将继续通过RM进行调度):
属性 | 描述 | 默认值 |
---|---|---|
yarn.nodemanager.distributed-scheduling.enabled | 启用分布式调度。 | 假 |
为了将作业提交到已打开AMRMProxy的群集,必须为要从中提交作业的客户端创建一组单独的配置。在这些文件中,conf / yarn-site.xml应该具有以下附加配置:
属性 | 值 | 描述 |
---|---|---|
yarn.resourcemanager.scheduler.address | 本地主机:8049 | 将作业重定向到节点管理器的AMRMProxy端口。 |
以下命令可用于运行示例pi map-reduce作业,使用机会性容器执行40%的映射器:
$ hadoop jar share / hadoop / mapreduce / hadoop-mapreduce-examples-3.2.1.jar pi -Dmapreduce.job.num-opportunistic-maps-percent =“ 40” 50100
通过在上述命令中更改mapreduce.job.num-opportunistic-maps-percent的值,我们可以指定可以通过机会容器执行的映射程序的百分比。
另一个示例作业是分布式外壳程序,它允许我们在一组容器上运行给定的外壳程序命令。以下命令可用于在10个机会容器中运行sleep 10命令:
$ yarn org.apache.hadoop.yarn.applications.distributedshell.Client -jar share / hadoop / yarn / hadoop-yarn-applications-distributedshell-3.2.1.jar.jar -shell_command sleep -shell_args 10 -num_containers 10 -container_type OPPORTUNISTIC
通过在以上命令中将container_type的值更改为OPPORTUNISTIC或GUARANTEED,我们可以指定要在机会性或有保证的容器中运行的任务。默认类型为GUARANTEED。通过将标志-promote_opportunistic_after_start添加到上述命令中,应用程序主服务器将在启动所有机会容器后尝试将其提升为有保证的容器。通过在上面的命令中添加标志“ -enforce_execution_type”,调度程序将遵循容器的执行类型。
YARN(公平和容量调度程序)中的现有调度程序仅在调度容器时在该节点上有未分配资源的情况下才将容器分配给该节点。这种有保证的执行类型的优点是,一旦AM将容器分派给节点,该容器的执行将立即开始,因为可以保证有可用资源。此外,除非违反公平性或容量限制,否则可以保证容器在不抢占先机的情况下运行完毕。
尽管此设计提供了更可预测的任务执行,但它有两个主要缺点,这些缺点可能导致集群资源利用率不理想:
为了缓解上述问题,除了现有的容器(以下称为保证容器)之外,我们还引入了机会容器的概念。即使在调度时没有机会性容器,也可以将机会性容器调度到NM。在这种情况下,机会容器将在NM处排队,等待资源变得可用以开始执行。机会容器的优先级低于保证容器的优先级,这意味着可以抢占保证容器以开始执行它们。因此,它们可用于提高群集资源利用率,而不会影响现有保证容器的执行。
机会容器的另一个优点是,它们在NM处引入了执行优先级的概念。例如,不需要严格执行保证的低优先级作业可以使用机会容器或混合容器执行类型来执行其任务。
我们介绍了两种分配机会容器的方法:集中式容器和分布式容器。在集中式调度中,机会容器是通过YARN RM分配的,而在分布式容器中是通过驻留在每个NM处的本地调度器分配的。集中分配可以实现更高质量的放置决策,并可以在应用程序之间实施更多参与的共享策略(例如,公平性)。另一方面,分布式调度可以提供更快的容器分配,这对于短期任务很有用,因为它避免了往返RM的麻烦。在这两种情况下,保证容器的调度均保持不变,并通过YARN RM(使用现有的Fair或Capacity Scheduler)进行。
请注意,在当前实现中,我们基于已分配(而不是未利用)的资源分配容器。因此,我们解决了上面提到的“反馈延迟”问题,但没有解决“已分配资源与已利用资源”的问题。正在进行的工作(YARN-1011)也使用机会容器来解决后一个问题。
下面,我们将更详细地描述容器执行类型,以及执行(包括在NM处的容器排队)和机会容器的分配。然后,我们讨论如何通过一些高级配置参数来微调机会容器。最后,我们讨论未完成的项目以供将来工作。
我们介绍以下两种类型的容器:
当AM将其资源请求提交给RM时,它将为每个容器指定类型(保证默认),从而确定容器的分配方式。随后,当容器由AM在NM启动时,其类型决定了NM 将如何执行该容器。
当容器到达NM时,其执行由NM处的可用资源和容器类型决定。保证容器会立即开始执行,如果需要,NM将终止正在运行的机会容器,以确保有足够的资源来启动保证容器。另一方面,如果机会容器在到达NM时没有资源可用于开始执行,则可以在NM处排队。为此,我们通过允许每个节点处的容器排队来扩展NM。NM监视本地资源,并且在有足够的可用资源时,它开始执行位于队列开头的机会容器。
特别是,当容器到达NM时,将执行本地化(即,下载所有必需的资源),然后容器进入SCHEDULED状态,在该状态下,将容器排队,等待其开始执行:
在下面的将来的工作项目中,我们讨论优先级任务执行(队列重新排序)和杀死机会容器以为有保证的容器腾出空间的不同方法。
如上所述,我们提供了集中式和分布式的机会容器分配方式,我们将在下面进行介绍。
我们在RM上引入了一项新服务,即OpportunisticContainerAllocatorAMService,它扩展了ApplicationMasterService。启用集中式机会分配后,来自AM的资源请求由OpportunisticContainerAllocatorAMService在RM端进行服务,该服务将它们分为两组资源请求:
该OpportunisticContainerAllocator保持与清单最小负载的节点在每个时刻的循环方式的群集,并且受让人容器他们。请注意,在当前实现中,我们故意不考虑节点位置约束。由于机会容器(与保证容器不同)可能会在NM开始执行之前在NM的队列中等待,因此将其分配给负载较小的节点(即,排队延迟将较小的节点)而不是尊重节点更为重要。它的位置限制。此外,目前我们还没有考虑机会容器的共享(公平/容量)限制。如果需要,将来可以添加对位置和共享约束的支持。
为了启用机会容器的分布式调度,我们在每个NM处引入了一项称为AMRMProxyService的新服务。所述AMRMProxyService实现ApplicationMasterService协议,并作为在该节点和RM运行的AM之间的代理。当AMRMProxyService时(通过参数)启用,我们强迫在特定节点上运行所有AMS与沟通AMRMProxyService同一节点,而不是直接到RM,。此外,为了确保本队不会与RM,当一个新的AM被初始化,我们更换了直接对话AMRMToken由签署令牌AMRMProxyService。
拦截器链可以向AMRMProxyService注册。这些拦截器之一是DistributedScheduler,它负责以分布式方式分配机会容器,而无需联系RM。这种模块化设计使AMRMProxyService在其他情况下也能发挥作用,例如YARN联合(YARN-2915)或限制行为异常的AM,只需在拦截器链上添加其他拦截器即可启用。
启用分布式机会调度后,每个AM会将其资源请求发送到在同一节点上运行的AMRMProxyService。该AMRMProxyService拆分的资源请求为两组:
在上述集中式机会调度的情况下,以上过程类似于由OpportunisticContainerAllocatorAMService执行的过程。主要区别在于,在分布式情况下,将请求分为保证的和机会的请求本地发生在节点上,并且仅将保证的请求转发到RM,而机会的请求则在不联系RM的情况下进行处理。
每个NM通过NM-RM心跳定期向RM通知运行中的保证容器和机会容器的数量,以及排队的机会容器的数量。RM从所有节点收集此信息,并确定负载最少的节点。
在机会容器的集中分配的情况下,该信息可立即获得,因为分配是集中发生的。在分布式调度的情况下,通过从RM到NM的心跳响应,将具有最少负载节点的列表传播到所有NM(从而可用于DistributedSchedulers)。发送到NM的最小负载节点数是可配置的。
目前,我们仅考虑每个节点上排队的机会容器的数量,以便估计机会容器发送到该节点时必须等待的时间,从而确定负载最少的节点。如果AM向我们提供了有关估计任务持续时间的信息,我们可以考虑它们,以便更好地估计队列等待时间。
有时可能会为机会性容器做出较差的放置选择(由于过长的队列长度估计),这可能导致节点之间的负载不平衡。在集群负载较高的情况下,以及在分布式调度的情况下(多个DistributedSchedulers可能会将容器放在同一NM,因为它们彼此不协调)。为了处理NM队列之间的负载不平衡,我们执行减载以动态地重新平衡NM之间的负载。特别是,在以RM汇总每个NM发布的队列时间估计值的同时,我们构造了一个分布并找到了NM队列长度的目标最大值(基于分布的均值和标准差)。然后,RM通过心跳响应将此值传播给各个NM。随后,使用此信息,队列长度大于阈值的节点上的NM丢弃机会性容器以满足该最大值。这迫使关联的各个AM将这些容器重新安排到其他位置。
本文档开头的快速指南中介绍了启用机会容器分配以及在集中式分配和分布式分配之间进行选择的主要属性。在这里,我们介绍了更高级的配置。请注意,在大多数情况下,对那些参数使用默认值就足够了。下面的所有参数都必须在conf / yarn-site.xml文件中定义。
为了确定调度机会性容器时将使用的最小负载节点数以及刷新此列表的频率,我们使用以下参数:
属性 | 描述 | 默认值 |
---|---|---|
纱线,资源管理器,机会性容器分配节点使用 | 机会容器分配器在容器分配期间将用于分配容器的最小负载节点数。较高的值可以改善大型群集中的负载平衡。 | 10 |
yarn.resourcemanager.nm容器排队排序节点间隔ms | 计算最小负载节点的频率。 | 1000 |
如以上节点负载平衡部分所述,RM定期收集所有NM队列长度,并计算其平均值(avg)和标准偏差(stdev)以及值avg + k * stdev(其中k a浮动)。此值通过NM-RM心跳传播到所有NM,只要它们的当前队列长度在queue_min_length和queue_max_length值之间(应使用这些值来避免出队),它们应通过使容器出队(如果需要)来尊重该值。分别从非常短的队列中执行任务和从长队列中积极地使任务出队)。参数k,可以如下指定queue_min_length和queue_max_length:
属性 | 描述 | 默认值 |
---|---|---|
yarn.resourcemanager.nm容器排队队列限制stdev | 该ķ参数。 | 1.0f |
纱线。资源管理器.nm容器排队。最小队列长度 | 该queue_min_length参数。 | 5 |
纱线。资源管理器.nm容器队列。最大队列长度 | 该queue_max_length参数。 | 15 |
最后,在使用分布式调度的情况下,还有两个属性可以进一步调整AMRMProxyService:
属性 | 描述 | 默认值 |
---|---|---|
yarn.nodemanager.amrmproxy.address | AMRMProxyService绑定到的地址/端口。 | 0.0.0.0:8049 |
yarn.nodemanager.amrmproxy.client.thread-count | 每个NM用于服务拦截器的线程数由不同的作业注册到AMRMProxyService。 | 3 |
在这里,我们描述了多种方式,可以扩展/增强机会容器的分配和执行。我们还提供了跟踪每个项目的JIRA。