• 关于Yarn的学习

1、YARN的应用

一、关于Yarn的学习

 

一些分布式计算框架(MapReduce,Spark等等)作为YARN应用运行在集群计算层(YARN)和集群存储层(HDFS和HBase)上。

还有一层应用是建立在上图所示的框架之上。如PIg,Hive和Crunch都是运行在MR、Spark之上的处理框架。

  1. YARN的运行机制

YARN通过两类长期运行的守护进程提供自己的核心服务:管理集群行资源使用的资源管理器(resource manager)、运行在集群中所有节点上且能够启动和监听容器(container)的节点管理器(node manager)。容器用于执行特定应用程序的进程、每个容器都有资源限制(内存、CPU等)。一个容器可以是一个Unix进程,也可以是一个Linux cgroup,取决于YARN的配置。

一、关于Yarn的学习

为了在YARN上运行了一个应用

1客户端联系资源管理器,要求它运行一个applicaton master 进程。

2a/2b资源管理器找到一个能够在容器中启动application master 的节点管理器。

准确的说,application master 一旦运行起来后能够做什么都依赖于应用本身。有可能是在所处的容器中简单运行一个计算,并将结果返回给客户端。

3向资源管理器请求更多的容器,

4a/4b以运行一个分布式计算。

  1. 资源请求

YARN有一个灵活的资源请求模型。当请求多个容器时,可以指定每个容器需要的计算机资源数量(内存和CPU),还可以指定对容器的本地限制要求。

本地化对于确保分布式数据处理算法高效使用集群带宽非常重要,因此,YARN允许一个应用为所申请的容器指定本地限制。本地限制可用于申请位于指定节点或机架,或集群中任何位置(机架外)的容器。

有时本地限制无法被满足,这种情况下要么不分配资源,或者可选择放松限制。例如一个节点由于已经运行了别的容器而无法再启动新的容器,这时如果有应用请求该节点,则YARN将尝试在同一机架中的其他节点上启动一个容器,如果还不行,则会尝试集群中任何一个节点。

通常情况下,当启动一个容器用于处理HDFS数据块(为了MapReduce中运行一个map任务)时,应用将会向这样的节点申请容器:存储该数据块三个复本的节点,或是存储这些复本的机架中的一个节点。如果申请失败,则申请集群中的任意节点。

YARN应用可以在运行中的任意时刻提出资源申请。例如,可以在最开始提出所有的请求,或者为了满足不断变化的应用需要,采取更为动态的方式在需要更多资源提出请求。

Spark采用了上述第一种方式,在集群上启动固定数量的执行器。另一方面,MapReduce则分两步走,在最开始时申请map任务容器,reduce任务容器的启用则放在后期。同样,如果任何任务出现失败,将会另外申请容器以重新运行失败的任务。

  1. 应用生命周期

YARN应用的生命周期差异很大:有几秒的短期应用,也有连续运行几天甚至几个月的长期应用。与其关注应用运行多长时间,不如按照应用到用户运行的作业之间的映射关系对应用进行分类更有意义。最简单的模型是一个用户作业对应一个应用,这也是MapReduce采取的方式。

第二种模型是,多个用户共享一个长期运行的应用。这种应用通常是作为一种协调者的角色在运行。

  1. 构建YARN应用

如果你有兴趣运行一个作业的有向无环图,那么Spark或Tez就很合适;如果对流处理有兴趣,Spark、Samza或Storm能提供帮助。

3、YARN和MapReduce1相比

MapReduce 1 中,有两类守护进程控制着作业执行过程,一个JobTracker及一个或多个TaskTracker。jobtracker通过调度tasktracker上运行任务来协调所有运行在系统上的作业。tasktracker在运行任务的同时将运行进度报告给jobtracker,jobtracker由此记录每项作业任务的整体进度情况。如果其中一个任务失败,jobtracker可以在另一个tasktracker节点上重新调度该任务。

MapReduce 1 中,jobtracker同时负责作业调度(将任务与tasktracker匹配)和任务进度监控(跟踪任务,重启失败或迟缓的任务;记录任务流水,如维护任务计数器的计数)。相比之下,YARN中,这些职责是由不同的实体担负的:它们分别是资源管理器和application master(每个MapReduce一个),jobtracker也负责存储已完成作业的作业历史,但是也可以运行一个作业历史服务器作为一个独立的守护进程来取代jobtracker。在YARN中,与之等价的角色是时间轴服务器(timeline server),它主要用于存储应用历史。

YARN中与tasktracker等价的角色是节点服务器。

MapReduce 1

YARN

JobTracker

资源管理器、 application master、时间轴服务器

TaskTracker

节点管理器

Slot

容器

 

使用YARN的好处:

  1. 可扩展性availability

与Map Reduce 1相比,YARN可以在更大规模的集群上运行。当节点数达到4000,任务数达到40000时,MapReduce 1会遇到瓶颈,瓶颈源于jobtracker必须同时管理作业和任务这样一个事实。YARN利用其资源管理器和application master分离的架构优点克服个这个局限性,可以扩展到将近10000个节点和100000个任务。

与jobtracker相比,一个应用的每个实例(这个指一个MapReduce作业)都对应一个专门的application master,该管理进程(master)在应用的持续期间运行。这个模型实际上与初始的Google MapReduce更为接近。论文中描述了如何启动一个管理(master)进程以协调运行在一系列工作(worker)上的map和reduce任务。

  1. 可用性scalability

当服务守护进程失败后,通过为另一个守护进程复制接管工作所需的状态以便其继续提供服务,从而可以获得高可用性(HA availability)。然而,jobtracker内存中大量快速变化的复杂状态(例如,每个任务状态每几秒会更新一次)使得改进jobtracker服务获得高可用性非常困难。

由于YARN中jobtracker在资源管理器和application master之间进行了职责划分,高可用的服务随之成为一个分而治之问题:先为资源管理器提供高可用性,再为YARN应用(针对每个应用)提供高可用性。实际上,对于资源管理器和application master,Hadoop 2 都支持MapReduce 作业的高可用性。

  1. 利用率Utilization

MapReduce 1中,每个tasktracker都配置有若干固定长度的slot,这些slot是静态分配的,在配置的时候就被划分为map slot和reduce slot。一个map slot仅能用于运行一个map任务,同样,一个reduce slot仅能用于运行一个reduce任务。

YARN中,y一个节点管理器管理一个资源池,而不是指定的固定数目的slot。YARN上运行的MapReduce不会出现由于集群仅有map slot可用导致reduce任务必须等待的情况,而MapReduce 1 则会有这样的问题。如果能够获得运行任务的资源,那么应用就会正常进行。

更进一步,YARN中的资源是精细化管理的,这样一个应用能够按需请求资源,而不是请求一个不可分割的,对于特定的任务而言可能贵太大(浪费资源)或太小(可能会导致失败)的slot。

  1. 多租户multienancy

在某种程度上,可以说YARN的最大优点在于向MapReduce以外的其他类型分布式应用开放了Hadoop。MapReduce仅仅是许多YARN应用的一种。

用户甚至可以在同一个YARN集群上运行不同版本的MapReduce,这使得升级MapReduce的过程更好管理(注意,MapReduce的一些组件,例如作业历史服务器和shuffle句柄,和YARN一样,仍然需要在集群范围内升级。)

4、YARN中调度

理想情况下,YARN应用发出的资源请求应该立刻给予满足。然而现实中资源是有限的,在一个繁忙的集群上,一个应用经常需要等待才能得到所需资源。YARN调度器的工作就是根据既定策略为应用分配资源。调度通常是一个难题,并且没有一个所谓”最好“的策略,这也是为什么YARN提供了多种调度器和可配置策略给我们。

  1. 调度选项

YARN中有三种调度器可用:FIFO调度器(FIFO Scheduler)、容量调度器(Capacity Scheduler)、公平调度器(Fair Scheduler)。

FIFO调度器将应用放置在一个队列中,然后按照提交的顺序(先进先出)运行应用。首先为队列中第一个应用的请求分配资源,第一个应用的请求被满足后依此为队列中下一个应用服务。

FIFO调度器的优点是,简单易懂,不需要任何配置,但是不适合共享集群。大的应用会占用集群中的所有资源,所以每个应用必须等待直到轮到自己运行。在一个共享集群中,更适合使用容量调度器或公平调度器。这两种调度器都允许长时间运行的作业能及时完成,同时也允许正在进行较小临时查询的用户能够在合理时间内得到返回结果。

一、关于Yarn的学习

一、关于Yarn的学习

一、关于Yarn的学习

 

i中是FIFO调度器,小作业一直被阻塞,直到大作业完成。

ii是容量调度器,一个独立的专门队列保证小作业一提交就可以启动,由于队列容量是为那个中的作业保留的,因此这种策略是以整个集群的利用率为代价的。这意味着与使用FIFO调度器相比,大作业执行的时间要长。

iii公平调度器,不需要预留一定量资源,因为调度器会在所有运行的作业之间动态平衡资源。第一个(大)作业启动时,它也是唯一运行的作业,因此获得集群中所有资源。当第二个(小)作业启动时,它被分配到集群一半资源,这样每个作业都能公平共享资源。

注意,从第二个作业的启动到获得公平共享资源之间会有时间滞后,因此它必须等待第一个作业使用的容器用完并释放出资源。当小作业结束且不再申请资源后,大作业将回去再次使用全部的集群资源。最终的效果是:既得到了较高的集群利用率,又能保证小作业能及时完成。

  1. 容量调度器配置

容量调度器允许多个组织共享一个Hadoop集群,每个组织可以分配到全部集群资源的一部分。每个组织被配置一个专门的队列,每个队列被配置为可以使用一定的集群资源。队列可以进一步按层次划分,这样每个组织内的不同用户能够共享该组织队列所分配的资源。在一个队列内,使用FIFO调度策略对应用进行调度。

单个作业使用的资源不会超过其队列容量。然而,如果队列中有多个作业,并且队列资源不够用呢?这时如果仍有可用的空闲资源,那么容量调度器可能会将空余的资源分配给队列中的作业,哪怕这回超出队列容量。这称为“弹性队列”。

正常操作时,容量调度器不会通过强行中止来抢占容器。因此,如果一个队列一开始资源够用,然后随着需求增长,资源开始不够用时,那么这个队列就只能等着其他队列释放容器资源。缓解这种情况的方法是,为队列设置一个最大容量限制,这样这个队列就不会过多侵占其它队列的容量了。当然,这样做的是以牺牲队列弹性为代价的,因此需要在不断尝试和失败中找到一个合理的折中。

Capacity使用说明

 conf/yarn-site.xml 配置启用Capacity调度器

yarn.resourcemanager.scheduler.class 设置为  org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler

conf/capacity-scheduler.xml配置具体的队列树,一个例子如下:

<!--资源分配限制-->

               <property>

                <name>yarn.scheduler.capacity.root.queues</name>

                <value>a,b</value>

                <description>根节点下定义a,b两个子队列</description>

               </property>

               <property>

                <name>yarn.scheduler.capacity.root.a.queues</name>

                <value>a1,a2</value>

                <description>队列a之下再定义a1,a2两个子队列</description>

               </property>

               <property>

                <name>yarn.scheduler.capacity.root.b.queues</name>

                <value>b1</value>

<description>队列b之下定义b1子队列</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.capacity</name>

<value>40</value>

<description>int,定义a队列总体使用40%的资源</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.maximum-capacity</name>

<value>60</value>

<description>int,定义a队列最多使用60%的资源(弹性队列情况),如果设为-1则表示禁止弹性队列情况</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.minimum-user-limit-percent</name>

<value>25</value>

<description>int,定义a队列中对单一用户而言最多使用队列25%的资源(多个用户抢占,资源紧张发生争用时),如果设为100则表示不禁止单个用户使用上限</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.user-limit-factor</name>

<value>1.5</value>

<description>float,定义a队列对单一用户而言最多使用队列maximum-capacity*1.5的资源(单个或少量用户,资源大量空闲的时候)</description>

</property>

 

 <!--任务&应用程序运行限制-->

<property>

<name>yarn.scheduler.capacity.maximum-applications</name>

<value>100</value>

<description>int,定义整个队列树的每个队列同时运行或者等待的最大任务数.(硬性限制,之外的请求将直接拒绝),默认10000</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.maximum-applications</name>

<value>200</value>

<description>int,对队列a或子队列同时运行或者等待的最大任务数.(硬性限制,之外的请求将直接拒绝),默认10000</description>

</property>

<property>

<name>yarn.scheduler.capacity.maximum-am-resource-percent</name>

<value>0.1</value>

<description>float,定义整个队列树的可用于运行的ApplicationMaster的最大百分比资源(一般用于限制应用程序的并发限制),默认0.1(10%)</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.maximum-am-resource-percent</name>

<value>0.1</value>

<description>float,对队列a或子队列的可用于运行的ApplicationMaster的最大百分比资源(一般用于限制应用程序的并发限制),默认0.1(10%)</description>

</property>

 

<!--队列管理&权限-->

<property>

<name>yarn.scheduler.capacity.root.b.state</name>

<value>STOPPED</value>

<description>RUNNING,STOPPED 设定队列状态.如果队列被设定为停止,则不能提交任何应用程序给它以及它的子队列</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.acl_submit_applications</name>

<value>*</value>

<description>限制哪些用户可以向队列a提交应用程序,*表示不限</description>

</property>

<property>

<name>yarn.scheduler.capacity.root.a.acl_administer_queue</name>

<value>*</value>

<description>限定哪些用户可以管理队列a中的应用程序</description>

</property>

 

<!--其它-->

<property>

<name>yarn.scheduler.capacity.resource-calculator</name>

<value>org.apache.hadoop.yarn.util.resource.DefaultResourseCalculator</value>

<description>资源比较调度器设置.默认为DefaultResourseCalculator只用内存比较,DominantResourceCalculator多维比较</description>

</property>

<property>

<name>yarn.scheduler.capacity.node-locality-delay</name>

<value>5</value>

<description>为错过调度机会的任务建立局部处理容器,应设置为集群节点数量,默认为40</description>

</property>

一、关于Yarn的学习

一、关于Yarn的学习

公平调度器的使用由属性yarn.resourcemanager.scheduler.class的设置所决定的。默认是使用容量调度器(尽管一些Hadoop分布式项目,如CDH中默认使用公平调度器),如果要使用公平调度器,需要将yarn-site.xml文件中的yarn.resourcemanager.scheduler.class设置为公平调度器的完全限定名:apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler。

一、关于Yarn的学习

一、关于Yarn的学习

文件capacity-scheduler.xml。在root队列定义两个队列:prod和dev。分别占40%和60%的容量。需要注意的是,对特定队列进行配置时,是通过以下形式的配置属性yarn.scheduler.capacity.<queue-path>.<sub-capacity>进行设置的。dev队列进一步被划分成eng和science两个容量相等的队列。由于dev队列的最大容量被设置为75%,因此即使prod队列空闲,dev队列也不会占用群不集群资源。

 

 

换而言之,prod队列能即刻使用的可用资源比例总是能达到25%。由于没有对其它队列设置最大容量限制,eng或science中的作业可能会占用dev队列的所有容量(将近75%的集群资源),而prod队列实际则可能会占用集群全部资源。

  1. 队列放置

将应用放置哪个队列取决于应用本身。例如,在MapReduce中,可以通过设置属性mapreduce.job.queuename来指定要用的队列。如果队列不存在,则在提交时会发送错误。如果不指定队列,那么应用将被放在一个名为“default”的默认队列中。

  1. 公平调度器配置

公平调度器旨在为所有运动的应用公平分配资源。

一、关于Yarn的学习

想象两个用户A和B,分别拥有自己的队列。A启动一个作业,在B没有需求时A会分配到全部可用资源;当A的作业仍在运行时B启动一个作业,一段时间后,按照我们先前看到的方式,每个作业都用到了一半的集群资源。这时,如果B启动第二个作业且其他作业仍在运行,那么第二个作业将和B的其他作业(这里是第一个)共享资源,因此B的每个作业将占四分之一的集群资源,而A仍继续占用一半的集群资源。最终的结果就是资源在用户之间实现了公平共享。

  1. 启用公平调度器

Fair调度器的配置文件fair-scheduler.xml文件
若没有这个配置文件,调度器会在用户提交第一个应用时为其自动创建一个队列,队列的名字就是用户名,所有的应用都会被分配到相应的用户队列中

启用公平调度器

yarn-site.xml 

<property>

   <name>yarn.resourcemanager.scheduler.class</name>

   <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>

</property>

yarn-site.xml公平调度配置
yarn.scheduler.fair.allocation.file  公平调度配置文件地址,默认为 fair-scheduler.xml
yarn.scheduler.fair.user-as-default-queue 是否使用用户名作为默认队列名称,如果队列名称没有指定。如果这个设置为“false”或未设置,所有工作有一个共享的默认队列,命名为“默认”。默认值为true。如果队列安置政策是在配置文件中,该属性将被忽略
yarn.scheduler.fair.preemption  是否使用资源抢占,默认为false
yarn.scheduler.fair.preemption.cluster-utilization-threshold 在该阈值之后发生抢占,默认为0.8
yarn.scheduler.fair.sizebasedweight 在队列内部分配资源时,默认采用公平轮询的策略分配资源,该配置将改变策略为按照应用程序资源需求数目分配资源,即应用程序需求越多,分配的资源越多.默认为false
yarn.scheduler.fair.assignmultiple  是否启动批量分配功能.当一个节点出现大量资源时,可以一次分配完成,也可以多次分配完成。默认值为false
yarn.scheduler.fair.max.assign 如果启动批量分配功能,则指定一次分配的最大Container数量。默认为-1没有限制
yarn.scheduler.fair.locality.threshold.node 当应用程序请求某个节点上资源时,它可以接受的可跳过的最大资源调度机会.默认情况下,该值为-1.0,表示不跳过任何调度机会
          当按照分配策略,可将一个节点上的资源分配给某个应用程序时,如果该节点不是应用程序期望的节点,可选择跳过该分配机会暂时将资源分配给其他应用程序,直到出现满足该应用程序需的节点资源出现。
          通常而言,一次心跳代表一次调度机会,而该参数则表示跳过调度机会占节点总数的比例
yarn.scheduler.fair.locality.threshold.rack 当应用程序请求某个机架上资源时,它可以接受的可跳过的最大资源调度机会。默认值为-1.0时表示没有通过任何调度的机会
yarn.scheduler.fair.allow-undeclared-pools 禁止自动创建(提交队列不存在)队列。默认值为true。如果队列安置政策是在配置文件中,该属性将被忽略
yarn.scheduler.fair.update-interval-ms 锁定的时间间隔调度器,重新计算需求,并检查是否将抢占间隔时间。默认为500毫秒

yarn.scheduler.increment-allocation-mb 内存规整化单位,默认是1024,这意味着,如果一个Container请求资源是1.5GB,则将被调度器规整化为ceiling(1.5 GB / 1GB) * 1G=2GB
yarn.scheduler.increment-allocation-vcores:虚拟CPU规整化单位,默认是1,含义与内存规整化单位类似

 

  1. 队列配置

通过一个名为fair-scheduler.xml的分配文件对公平调度器进行配置, 该文件位于类路径下。



队列配置文件(可以在运行时完成修改最小共享,资源限制,权重,超时抢占以及队列调度策略等。调度器会每个10-15秒重载修改后的该配置文件):
quque
minResources:最少资源保证量,设置格式为“X mb, Y vcores”
                  当一个队列的最少资源保证量未满足时,它将优先于其他同级队列获得资源,对于不同的调度策略(后面会详细介绍),最少资源保证量的含义不同,
                    对于fair策略,则只考虑内存资源,即如果一个队列使用的内存资源超过了它的最少资源量,则认为它已得到了满足;对于drf策略,则考虑主资源使用的资源量,即如果一个队列的主资源量超过它的最少资源量,则认为它已得到了满足
maxResources:一个队列允许的最大资源,采用“X mb, Y vcores”的形式。对于单一资源公平策略,vcores的值会被忽略。一个队列永远不会分配资源总量超过这个限制
maxRunningApps:最多同时运行的应用程序数目。通过限制该数目,可防止超量Map Task同时运行时产生的中间输出结果撑爆磁盘
maxAMShare:限制队列用于运行Application Master的资源比例。这个属性只能用于叶子队列。比如,如果设置为1.0f,那么在这个队列的AMs可以占用100%的内存和CPU的公平共享。这个值为-1.0f将会禁用该特性并且amShare不会进行校验。默认值是0.5f
weight:与其他队列非比例的分享集群。权重默认是1,权重是2的队列将会收到接近默认权重2倍的资源
schedulingPolicy:任一队列都可以设置调度策略。允许的值包括“fifo”,“fair”,“drf”或者其他任何继承.默认fair
aclSubmitApps:可以提交apps到队列的用户或者组的列表。要获得更多信息可以参考下面的ACLs部分,关于列表的格式和ACLs如何发挥作用
aclAdministerApps:可以管理队列的用户或者组列表。当前唯一的管理动作就是杀死应用程序。要获得更多信息可以参考下面的ACLs部分,关于列表的格式和ACLs如何发挥作用
minSharePreemptionTimeout:队列处在最小共享之下,在尝试抢占其他队列的资源之前的秒数。如果不设置,队列将会总其父队列继承这个值
fairSharePreemptionTimeout:队列处在最小公平共享阈值之下,在尝试抢占其他队列的资源之前的秒数。如果不设置,队列将会总其父队列继承这个值
fairSharePreemptionThreshold:队列的公平共享抢占阈值。如果队列等待fairSharePreemptionTimeout之后没有接收到fairSharePreemptionThreshold*fairShare的资源,它被允许从其他队列抢占资源。如果不设置,队列将会总其父队列继承这个值
User
maxRunningApps:对特定用户可以运行的apps的数量限制
userMaxAppsDefault:设置任意用户(没有特定限制的用户)运行app的默认最大数量限制
defaultFairSharePreemptionThreshold:设置root队列的公平共享抢占的默认阈值;可以被root队列下的fairSharePreemptionThreshold 覆盖
queueMaxAppsDefault:设置队列的默认运行app数量限制;可以被任一队列的maxRunningApps元素覆盖
queueMaxAMShareDefault:设置队列的默认AM共享资源限制;可以被任一队列的maxAMShare 元素覆盖
defaultQueueSchedulingPolicy:设置队列的默认调度策略;可以在任一队列中设置schedulingPolicy 进行覆盖该默认值。默认值为“fair”
queuePlacementPolicy:包含一个Rule元素列表用于告诉调度器如何放置app到队列Rule生效顺序与列表中的顺序一致。Rule可以含有参数。
所有Rule接受"create"参数,用于标明该规则是否能够创建新队列."Create"默认值为true;如果设置为false并且Rule要放置app到一个allocations file没有配置的队列,那么继续应用下一个Rule。最后的Rule绝不能执行Continue
specified:app放置到它请求的队列。如果没有请求队列,例如它指定"default",执行continue。如果app请求队列以英文句点开头或者结尾,例如 “.q1” 或者 “q1.” 将会被拒绝
user:app按照提交用户名放置到同名的队列。用户名中的英文句点将会被“_dot_”替换,如对于用户"first.last"的队列名是"first_dot_last"
primaryGroup:app放置到与提交用户primary group同名的队列。用户名中的英文句点将会被“_dot_”替换,如对于组"one.two"的队列名是"one_dot_two"
secondaryGroupExistingQueue:app放置到与提交用户所属的secondary group名称相匹配的队列。
                            第一个与配置相匹配的secondary group将会被选中。组名中的英文句点会被替换成“_dot_”,例如用户使用“one.two”作为他的secondary groups将会放置到“one_dot_two”队列,如果这个队列存在的话
nestedUserQueue: app放置到根据队列中嵌套规则建议的用户名同名的队列中。
                    这有些类似于UserRule,在‘nestedUserQueue’规则中不同的是用户队列可以创建在任意父队列下,而'user'规则只能在root队列下创建用户队列。
                    有一点需要注意,nestedUserQueue 规则只有在嵌入规则返回一个父队列时才会生效。用户可以通过设置 队列的‘type’属性为 ‘parent’ 来配置父队列,或者在队列下至少配置一个叶子
default: app放置到default规则中指定的 ‘queue’属性对应的队列。如果 ‘queue’属性没有指定,app放置到 ‘root.default’ 队列
reject:拒绝app

<?xml version="1.0"?>

<allocations>

   <queue name="sample_queue">

     <minResources>10000 mb,0vcores</minResources> <!--最少资源保证量,设置格式为“X mb, Y vcores”-->

     <maxResources>90000 mb,0vcores</maxResources> <!--最多可以使用的资源量-->

     <maxRunningApps>50</maxRunningApps> <!--最多同时运行的应用程序数目。通过限制该数目,可防止超量Map Task同时运行时产生的中间输出结果撑爆磁盘-->

     <maxAMShare>0.1</maxAMShare>

     <weight>2.0</weight>

     <schedulingPolicy>fair</schedulingPolicy> <!--队列采用的调度模式,可以是fifo、fair或者drf-->

     <queue name="sample_sub_queue"> <!--定义子队列-->

       <aclSubmitApps>charlie</aclSubmitApps>

       <minResources>5000 mb,0vcores</minResources>

     </queue>

   </queue>

 

  <queueMaxAMShareDefault>0.5</queueMaxAMShareDefault>

 

   <!—- Queue 'secondary_group_queueue' is a parent queue and may have user queues under it -->

   <queue name="secondary_group_queue" type="parent">

   <weight>3.0</weight>

   </queue>

  

   <user name="sample_user"> <!--为单个用户设置最多同时运行应用程序的数目-->

     <maxRunningApps>30</maxRunningApps>

   </user>

   <userMaxAppsDefault>5</userMaxAppsDefault>

  

   <queuePlacementPolicy>

     <rule name="specified" />

     <rule name="primaryGroup" create="false" />

    <rule name="nestedUserQueue">

         <rule name="secondaryGroupExistingQueue" create="false" />

     </rule>

     <rule name="default" queue="sample_queue"/>

   </queuePlacementPolicy>

</allocations>

一、关于Yarn的学习

队列的层次使用嵌套queue元素来定义。所有的队列都是root队列的孩子,即使实际上并没有嵌套进root queue元素里。这里把dev队列又划分成eng和science两个队列。

队列中有权重元素,用于公平共享计算。在这个例子中,当集群资源按照40:60的比例分配给prod和dev时,集群分配被认为是公平的。eng和science队列没有制定权重,因此它们会被平均分配。权重并不是百分之百,例子中是为了简单起见使用了相加之和为100的两个数。y也可以为prod和dev队列分别指定2和3的权重,在效果上是一样的。

每个队列可以有不同的策略。队列的默认调度策略可以通过顶层元素defaultQueueSchedulingPolicy进行设置,如果省略,默认使用公平调度。尽管名称为“公平”,公平调度器也支持队列级别的FIFO策略,以及Dominant Resource Fairness 策略。

队列的调度策略可以被队列的schedulingPolicy元素指定的策略覆盖。在上述例子中,由于我们希望每个生产性作业能够顺序运行且最短可能的时间内结束,所以prod队列使用了FIFO调度策略。值得注意的是,在prod和dev队列之间、eng和science队列之间及内部划分资源仍然使用了公平调度。

尽管上述的分配文件中没有展示,每个队列仍k可配置最大和最小资源数量,及最大可运行的应用的数量。最小资源数量不是一个硬性的限制,但是调度器常用它对资源分配进行了优先排序。如果两个队列的资源都低于它们的公平共享额度,那么远低于最小资源数量的那个队列优先被分配资源。最小资源数量也会用于抢占行为。

  1. 队列放置

公平调度器使用一个基于规则的系统来确定应用应该放到哪个队列。queuePlacementPolicy元素包含了一个规则列表,每条规则会被依次尝试知道匹配成功。第一条规则,specified,表示把应用放在指明的队列中,如果没有指明,或如果所指明的队列不存在,则规则不匹配,继续尝试下一条规则。primaryGroup规则会试着把应用放在以用户的主Unix组命名的队列中,如果没有这样的队列,则继续尝试下一条规则而不是创建队列。Default规则是一条兜底规则,当前述规则都不匹配时,将启用该条规则,把应用放进dev.eng队列中。

当然,可以完全省略queuePlacementPolicy元素,此时队列放置默认遵从r如下规则:

一、关于Yarn的学习

换而言之,除非明确定义队列,否则必要时会以用户名为队列名创建队列。

另一个简单的队列放置策略是,将所有应用放进同一队列(default)中。这样可以在应用之间公平共享资源,而不是用户之间共享。等价于

一、关于Yarn的学习

不使用分配文件也可以设置以上策略,通过将属性yarn.scheduler.fair.user-as-default-queue设为false,应用就会被放入default队列,而不是各个用户的队列。另外,将属性yarn.scheduler.fair.allow-undeclared-pools设置为true,用户便不能随意创建队列了。

  1. 抢占

在一个繁忙的集群中,当作业被提交给一个空队列时,作业不会立刻启动,直到集群上已经运行的作业释放了资源。为了使作业从提交到执行所需的时间可预测,公平调度器支持“抢占”功能。

所谓抢占,就是允许调度器终止那些占用资源超过了其公平共享份额的队列的容器,这些容器资源释放后可以分配给资源数量低于应得份额的队列。注意,抢占会降低整个集群的效率,因为被终止的containers需要重新执行。

通过yarn.scheduler.fair.preemption设置为true,可以全面启动抢占功能。有两个相关的抢占超时设置:一个用于最小共享(minimum share preemption timeout),另一个用于公平共享(fair share preemption timeout),两者设定时间均为秒级。默认情况下,两个超时参数均不设置。所以为了允许抢占容器,需要至少设置其中一个超时参数。

如果队列在minimum share preemption timeout指定时间内未获得被承诺的最小共享资源,调度器就会抢占其他容器。可以通过分配文件中的顶层元素defaultMinSharePreemptionTimeout为所有队列设置默认的超时时间,还可以通过设置每个队列的minSharePreemptionTimeout元素来为单个队列指定超时时间。

类似,如果队列在fair share preemption timeout指定的时间内获得的资源仍然低于其公平共享份额的一半,那么调度器j就会抢占其他容器。可以通过分配文件中的顶层元素defaultFairSharePreemptionTimeout为所有队列设置默认的超时时间,还可以通过设置每个队列的fairSharePreemptionTimeout元素来为单个队列指定超时时间。通过设置defaultFairSharePreemptionThreshold和fairSharepreemptionThreshold(针对每个队列)可以修改超时阙值,默认值是0.5。

  1. 延迟调度

所有的YARN调度器都试图以本地请求为重。在一个繁忙的集群上,如果一个应用请求某个节点,那么极有可能此时有其他容器正在该节点上运行。显而易见的处理是,立刻放宽本地性需求,在同一机架中分配一个容器。然而,通过实践发现,此时如果等待一小段时间(不超过几秒),能够戏剧性的增加在所请求节点上分配到一个容器的机会,从而可以提高集群的效率,这个特性称之为延迟调度(delay scheduling)。容量调度器和公平调度器都支持延迟调度。

YARN中的每个节点管理器周期性的(默认每秒一次)向资源管理器发送心跳请求。心跳中携带了节点管理器中正运行的容器,新容器可用的资源等信息,这样对于一个计划运行一个容器的应用而言,每个心跳j就是一个潜在的调度机会(scheduling opportunity)。

当使用延迟调度时,调度器不会简单的使用它收到的第一个调度机会,而是等待设定的最大数目的调度机会发生,然后才放松本地性限制并接收下一个调度机会。

对于容量调度器,可以通过设置yarn.scheduler.capacity.node-locality-delay来配置延迟调度。设置为正整数,表示调度器在放松节点限制,改为匹配同一机架上的其他节点前,准备错过的调度机会的数量。

公平调度器也使用调度机会的数量来决定延迟时间,尽管是使用集群规模的比例来表示这个值。例如将yarn.scheduler.fair.locality.threshold.node设置为o.5,表示调度器在接受同一机架中的其他节点之间,将一直等待直到集群中的一半节点都已经给过调度机会。这个相关的属性yarn.scheduler.fair.locality.threshold.rack,表示接受另一个机架替代所申请的机架之前需要等待的时长阙值。

5、主导资源公平性

对于单一类型资源,如内存的调度,容量或公平性的概念很容易确定。例如两个用户正在运行应用,可以通过度量每个应用使用的内存来比较两个应用。然而,当有多种资源类型需要调度时,事情就会变得复杂。例如,如果一个用户的应用对CPU的需求量很大,但内存的需求量很少,而另一个用户需要很少的CPU,但对内存需求量很大,那么如何比较这两个应用?

YARN中调度器解决这个问题的思路是,观察每个用户的主导资源,并将其作为对集群资源使用的一个度量。这方法称为“主导资源公平性”(Dominant Resource Fairness,DRF)。解释如下:

默认情况下不用DRF,因此在资源计算期间,只需要考虑内存,不必考虑CPU。对容量调度器进行配置后,可以使用DRF,将capacity-scheduler.xml文件的org.apache.hadoop.yarn.util.resource.DominantResourceCaculator设为yarn.scheduler.capacity.resource-caculator即可。

公平调度器若要使用DRF,通过将分配文件中的顶层元素defaultQueueSchedulingPolicy设为drf即可。

 

相关文章:

  • 2022-12-23
  • 2021-12-13
  • 2021-10-27
  • 2021-09-14
  • 2021-07-18
  • 2021-05-18
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-08-03
  • 2022-01-01
  • 2021-07-04
  • 2021-12-11
  • 2021-11-29
  • 2022-01-08
相关资源
相似解决方案