Hadoop 文档

General

Common

HDFS

MapReduce

MapReduce REST APIs

YARN

YARN REST APIs

YARN Service

Submarine

Hadoop Compatible File Systems

Auth

Tools

Reference

Configuration

目的

本文档介绍了机会容器执行的概念,并讨论了机会容器的分配和执行方式。

快速指南

我们首先简要介绍机会容器,包括用户如何启用此功能以及使用此类容器运行示例作业。

主要目标

与仅在有未分配资源的情况下在节点中调度的现有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端口。

运行样本作业

MapReduce PI

以下命令可用于运行示例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的值更改为OPPORTUNISTICGUARANTEED,我们可以指定要在机会性或有保证的容器中运行的任务。默认类型为GUARANTEED。通过将标志-promote_opportunistic_after_start添加到上述命令中,应用程序主服务器将在启动所有机会容器后尝试将其提升为有保证的容器。通过在上面的命令中添加标志“ -enforce_execution_type”,调度程序将遵循容器的执行类型。

Web UI中的机会容器

启用机会容器分配后,可以在Web UI的“节点”页面(rm-address:8088 / cluster / nodes)中观察到以下新列:

  • 正在运行的容器(O):每个节点上正在运行的机会容器的数量;
  • 内存使用量(O):每个节点上的机会容器使用的总内存;
  • 使用的VCore(O):每个节点上的机会容器使用的CPU虚拟内核总数;
  • 排队的容器:每个节点上排队的容器数。

单击在节点上运行的特定容器时,还将显示该容器的执行类型。

在本文档的其余部分中,我们提供了机会容器的深入描述,包括有关它们的分配和执行的详细信息。

总览

YARN(公平和容量调度程序)中的现有调度程序仅在调度容器时在该节点上有未分配资源的情况下才将容器分配给该节点。这种有保证的执行类型的优点是,一旦AM将容器分派给节点,该容器的执行将立即开始,因为可以保证有可用资源。此外,除非违反公平性或容量限制,否则可以保证容器在不抢占先机的情况下运行完毕。

尽管此设计提供了更可预测的任务执行,但它有两个主要缺点,这些缺点可能导致集群资源利用率不理想:

  • 反馈延迟。当容器在节点上完成其执行时,RM将通过下一个NM-RM心跳通知有可用资源,然后RM在该节点调度一个新容器,AM将通过下一个AM-RM心跳通知,最后,AM在节点上启动新容器。这些延迟会导致节点资源闲置,进而导致资源利用率降低,尤其是在工作负载涉及持续时间相对较短的任务时。
  • 已分配资源与已利用资源。RM基于在每个节点上分配的资源来分配容器,这可能大大高于实际使用的资源(例如,考虑已为其分配4GB内存但仅使用2GB的容器)。这降低了有效的资源利用率,如果在调度过程中RM考虑到已利用的资源,则可以避免。但是,这必须以一种方式来实现,以防万一正在运行的容器的已利用资源增加,资源也可以被回收。

为了缓解上述问题,除了现有的容器(以下称为保证容器)之外,我们还引入了机会容器的概念。即使在调度时没有机会性容器,也可以将机会性容器调度到NM。在这种情况下,机会容器将在NM处排队,等待资源变得可用以开始执行。机会容器的优先级低于保证容器的优先级,这意味着可以抢占保证容器以开始执行它们。因此,它们可用于提高群集资源利用率,而不会影响现有保证容器的执行。

机会容器的另一个优点是,它们在NM处引入了执行优先级的概念。例如,不需要严格执行保证的低优先级作业可以使用机会容器或混合容器执行类型来执行其任务。

我们介绍了两种分配机会容器的方法:集中式容器和分布式容器。在集中式调度中,机会容器是通过YARN RM分配的,而在分布式容器中是通过驻留在每个NM处的本地调度器分配的。集中分配可以实现更高质量的放置决策,并可以在应用程序之间实施更多参与的共享策略(例如,公平性)。另一方面,分布式调度可以提供更快的容器分配,这对于短期任务很有用,因为它避免了往返RM的麻烦。在这两种情况下,保证容器的调度均保持不变,并通过YARN RM(使用现有的Fair或Capacity Scheduler)进行。

请注意,在当前实现中,我们基于已分配(而不是未利用)的资源分配容器。因此,我们解决了上面提到的“反馈延迟”问题,但没有解决“已分配资源与已利用资源”的问题。正在进行的工作(YARN-1011)也使用机会容器来解决后一个问题。

下面,我们将更详细地描述容器执行类型,以及执行(包括在NM处的容器排队)和机会容器的分配。然后,我们讨论如何通过一些高级配置参数来微调机会容器。最后,我们讨论未完成的项目以供将来工作

容器执行类型

我们介绍以下两种类型的容器:

  • 保证的容器对应于现有的YARN容器。它们由Fair或Capacity Scheduler分配,并且一旦分配到节点,就可以确保有可用资源立即执行。而且,这些容器可以运行完成(只要没有故障)。仅当它们所属的调度程序的队列违反公平性或容量限制时,才可以抢占它们。
  • 机会容器不能保证有资源,当它们被分派到一个节点时就可以开始执行。相反,它们可能会在NM排队,直到资源可用为止。如果有保证的容器到达一个节点并且没有可用的资源,则将抢占一个或多个机会容器来执行有保证的容器。

当AM将其资源请求提交给RM时,它将为每个容器指定类型(保证默认),从而确定容器的分配方式。随后,当容器由AM在NM启动时,其类型决定了NM 将如何执行该容器。

机会容器的执行

当容器到达NM时,其执行由NM处的可用资源和容器类型决定。保证容器会立即开始执行,如果需要,NM将终止正在运行的机会容器,以确保有足够的资源来启动保证容器。另一方面,如果机会容器在到达NM时没有资源可用于开始执行,则可以在NM处排队。为此,我们通过允许每个节点处的容器排队来扩展NM。NM监视本地资源,并且在有足够的可用资源时,它开始执行位于队列开头的机会容器。

特别是,当容器到达NM时,将执行本地化(即,下载所有必需的资源),然后容器进入SCHEDULED状态,在该状态下,将容器排队,等待其开始执行:

  • 如果有可用资源,则无论其执行类型如何,都会立即开始执行容器。
  • 如果没有可用资源:
    • 如果容器得到保证,我们将杀死要执行的保证容器所需数量的运行机会容器,然后开始执行。
    • 如果容器是机会性的,则将其保留在队列中,直到资源可用为止。
  • 当某个容器(保证性或机会性)完成执行并释放资源时,我们检查排队的容器,如果有可用资源,则开始执行它们。我们以FIFO顺序从队列中选择容器。

在下面的将来的工作项目中,我们讨论优先级任务执行(队列重新排序)和杀死机会容器以为有保证的容器腾出空间的不同方法。

机会容器的分配

如上所述,我们提供了集中式和分布式的机会容器分配方式,我们将在下面进行介绍。

集中分配

我们在RM上引入了一项新服务,即OpportunisticContainerAllocatorAMService,它扩展了ApplicationMasterService。启用集中式机会分配后,来自AM的资源请求由OpportunisticContainerAllocatorAMService在RM端进行服务,该服务将它们分为两组资源请求:

  • 保证集转发到现有的ApplicationMasterService,然后由Fair或Capacity Scheduler处理。
  • 机会集由新的OpportunisticContainerAllocator处理,该OpportunisticContainerAllocator将机会容器调度到节点。

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拆分的资源请求为两组:

  • 保证集将转发到RM。在这种情况下,AMRMProxyService只是充当AM和RM之间的代理,并且容器分配保持不变(使用Fair或Capacity Scheduler)。
  • 机会集不转发给RM。相反,它由在节点本地运行的DistributedScheduler处理。特别是,DistributedScheduler维护一个列表,该列表包含集群中负载最少的节点,并以循环方式为它们分配容器。RM 通过NM-RM心跳定期通知DistributedScheduler有关负载最小的节点。

在上述集中式机会调度的情况下,以上过程类似于由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_lengthqueue_max_length值之间(应使用这些值来避免出队),它们应通过使容器出队(如果需要)来尊重该值。分别从非常短的队列中执行任务和从长队列中积极地使任务出队)。参数k可以如下指定queue_min_lengthqueue_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。

  • 资源超额使用YARN-1011)。如前所述,为了进一步提高群集资源的利用率,我们可以不基于分配的资源而是根据实际使用的资源来调度容器。当过量使用资源时,如果我们增加了已经运行的容器的已利用资源,则存在资源耗尽的风险。因此,应该对分配超出节点容量的容器使用机会执行。这样,我们可以选择机会容器来回收资源。
  • NM队列重新排序YARN-5886)。代替以FIFO顺序执行排队的容器,我们可以采用重新排序策略来动态确定下一个将要执行的机会容器。例如,我们可以优先处理预期运行时间短的容器或属于即将完成的应用程序的容器。
  • 在NM处无序地杀死YARN-5887)。如上所述,当我们需要释放资源以保证容器开始执行时,我们会按相反的到达顺序杀死机会容器(首先是最近启动的容器)。这可能并不总是正确的决定。例如,我们可能想要最小化被杀死的容器的数量,或者避免杀死非常接近完成的作业的容器。
  • 容器暂停YARN-5292):目前,我们杀死了机会主义的容器,以便在发生资源争用时为保证提供空间。在繁忙的群集中,这可能会降低群集的有效利用率:每当我们杀死一个正在运行的机会容器时,都必须重新启动它,这样我们就会失去工作。为此,我们可以暂停运行机会容器。请注意,这需要容器执行器(例如,使用的容器技术)和应用程序的支持。
  • 容器促销YARN-5085)。在某些情况下,在执行期间更改容器的执行类型可能会有所帮助。例如,应用程序可能会以机会主义的方式提交容器,并且在执行开始时,它可以请求将其提升为有保证的容器,以避免被杀死。