【Hadoop】08-YARN中的调度

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

1.调度选项

YARN中有三种调度器可用:FIFO调度器(FIFO Scheduler),容量调度器(Capacity Scheduler)和公平调度器(Fair Scheduler)。FIFO调度器将应用放置在第一个队列中,然后按照提交的顺序(先进先出)运行应用。首先为队列中第一个应用的请求分配资源,第一个应用的请求被满足后再一次为队列中下一个应用服务。

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

下图描述了调度器之间的差异性,由图中可以看出,当使用FIFO调度器(i)时,小作业一直被阻塞,直至大作业完成。

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

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


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

2.容量调度器配置

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

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

注:如果属性yarn.scheduler.capacity.<queue-path>.user-limit-factor设置为大于1(默认值),那么一个作业可以使用超过其队列容量的资源。

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

假设一个队列的层次结构如下:


如下范例是一个基于上述队列层次的容量调度器配置文件,文件名为capacity-scheduler.xml。在root队列下定义两个队列:prod和dev,分别占40%和60%的容量。需要注意的是,对特定队列进行配置时是通过以下形式的配置属性yarn.schduler.capacity.<queue-path>.<sub-property>进行设置的,其中<queue-path>表示队列的层次路径(用圆点隔开),例如root.prod。

容量调度器基本配置文件。

<?xml version="1.0"?>
<configuration>
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>prod,dev</value> 
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.queues</name>
    <value>eng,science</value> 
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.prod.capacity</name>
    <value>40</value>
  </property> 
  <property>
    <name>yarn.scheduler.capacity.root.dev.capacity</name>
    <value>60</value> 
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
    <value>75</value> 
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.eng.capacity</name>
    <value>50</value> 
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.dev.science.capacity</name>
    <value>50</value>
  </property>
</configuration>

可以看到dev队列进一步被划分为eng和science两个容量相等的队列。由于dev队列的最大容量被设置为75%,因此即使prod队列空闲dev队列也不会占用全部集群资源。换而言之prod队列能即刻使用的可用资源比例总是能达到25%,由于没有对其他队列设置最大容量限制,eng和science中的作业可能会占用dev队列的所有容量(将近75%的集群资源),而prod队列实际可能会占用全部集群资源。

除了可以配置队列层次和容量,还有些设置是用来控制单个用户或应用能被分配到的最大资源数量,同时运行的应用数量及队列的ACL认证等。

队列放置

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

对于容量调度器,队列名应该是队列层次名的最后一部分,完整的队列层次名是不会被识别的。例如,对于上述配置范例,prod和eng是合法的队列名,但root.dev.eng和dev.eng作为队列名是无效的。

3.公平调度器配置

公平调度器为所有运行的应用公平分配资源。上面的图展示了同一个队列中的应用是如何实现资源公平共享的。然而公平共享实际也可以在多个队列间工作,后续会对此进行分析。

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


启动公平调度器

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

队列配置

通过一个名为fair-scheduler.xml的分配文件对公平调度器进行配置,该文件位于类路径下。(可以通过设置属性yarn.scheduler.fair.allocation.file来修改文件名)。当没有该分配文件时,公平调度器的工作策略同先前所描述的一样:每个应用放置在一个以用户名命名的队列中,队列是在用户提交第一个应用时动态创建的。

通过分配文件可以为每个队列进行配置。这样可以对容量调度器支持的层次队列进行配置。例如可以像为容量调度器所做的那样,使用范例如下所示的分配文件定义prod和dev。

<?xml version="1.0"?>
<allocations>
  <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>

  <queue name="prod">
    <weight>40</weight>
    <schedulingPolicy>fifo</schedulingPolicy>
  </queue>

  <queue name="dev">
    <weight>60</weight>
    <queue name="eng" /> 
    <queue name="science" />
  </queue>

  <queuePlacementPolicy>
    <rule name="specified" create="false" />
    <rule name="primaryGroup" create="false" />
    <rule name="default" queue="dev.eng" />
  </queuePlacementPolicy>
</allocations>

队列的层次使用嵌套queue元素来定义。所有的队列都是root队列的孩子,即使实际上并没有嵌套进root queue元素里。这里把dev队列又划分成eng和science两个队列。队列中有权重元素用于公平共享计算。在这个例子中当集群资源按照40:60的比例分配给prod和dev时,集群分配被认为是公平的。eng和science队列没有指定权重因此他们会被平均分配。权重并不是百分百,例子中是为了简单起见使用了相加和为100的两个数。也可以为prod和dev队列分别指定2和3的权重,在效果上是一样的。

当设置权重时,记住要考虑默认队列和动态创建的队列(例如以用户名命名的队列)。虽然没有在分配文件中为他们指定权重,但他们仍有值为1的权重。

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

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

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

队列放置

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

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

<queuePlacementPolicy>
   <rule name="specified"/>
   <rule name="user"/>
</queuePlacementPolicy>

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

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

<queuePlacementPolicy>
   <rule name="default"/>
</queuePlacementPolicy>

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

4.抢占

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

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

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

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

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

4.延迟调度

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

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

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

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

5.延迟调度

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

YARN中调度器解决这个问题的思路是,观察每个用户的主导资源,并将其作为对集群资源使用的一个度量。这个方法称为“主导资源公平性”。这个思想用一个简单的例子就可以很好的给予解释。

想象一个总共有100个CPU和10TB的集群。应用A请求的每份容器资源为2个CPU和300GB内存,应用B请求的每份容器资源为6个CPU和100GB内存。A请求的资源在集群资源中占比分别为2%和3%,由于内存占比(3%)大于CPU占比(2%),所以内存是A的主导资源。B请求的资源在集群资源中占比分别为6%和1%,所以CPU是B的主导资源。由于B申请的资源是A的两倍(6% vs 3%),所以在公平调度下,B将分到一半的容器。

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

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

### 回答1: Hadoop YARN (Yet Another Resource Negotiator) 是一个基于Hadoop的集群资源管理系统。Hadoop YARN Client是Hadoop YARN的一部分,它是用来与YARN ResourceManager通信的客户端工具。 Hadoop YARN Client的主要功能是向YARN ResourceManager提交应用程序并获取集群的资源来执行这些应用程序。当一个应用程序需要在Hadoop集群上运行时,开发人员可以使用Hadoop YARN Client来编写和提交应用程序,然后该客户端将应用程序的相关信息发送给YARN ResourceManager。这些应用程序可以是MapReduce程序,也可以是其他类型的应用程序,例如Spark、Flink等。 使用Hadoop YARN Client,开发人员可以指定应用程序所需的计算资源和内存等配置参数。此外,Hadoop YARN Client还可以跟踪应用程序的状态,并显示有关应用程序执行进度和状态的相关信息。如果发生错误或异常,开发人员可以使用Hadoop YARN Client来取消或终止应用程序的执行。 Hadoop YARN Client利用YARN ResourceManager的资源调度功能,将应用程序提交给ResourceManager后,ResourceManager将根据集群的资源情况来分配相应的资源给该应用程序。此外,Hadoop YARN Client还可以与NodeManager通信,以获取有关执行任务的节点的信息,并监视应用程序的进度。 总的来说,Hadoop YARN Client提供了一个方便的方式来提交和管理应用程序的执行,并与YARN ResourceManager和NodeManager进行通信,以获取资源和监视应用程序的状态。通过使用Hadoop YARN Client,开发人员可以更容易地在Hadoop集群上运行和管理各种类型的应用程序。 ### 回答2: Hadoop YARN客户端是Hadoop生态系统的一个关键组件,用于与YARN资源管理器进行通信,并提交、监控和管理MapReduce作业或其他分布式计算任务。YARN(Yet Another Resource Negotiator)是Hadoop的资源管理器,负责集群资源的分配和任务的调度Hadoop YARN客户端的主要功能包括作业的提交和监控。当用户想要运行一个MapReduce作业时,他们可以使用YARN客户端来提交该作业。YARN客户端将作业的执行所需要的资源需求和其他相关信息发送给YARN资源管理器。资源管理器根据集群可用的资源和调度策略来分配资源,并将作业的任务分配给相应的节点上的容器来执行。 同时,YARN客户端还可以监控作业的执行进度和状态。用户可以通过YARN客户端查询和获取作业的相关信息,如已完成的任务数、失败的任务数、运行时间等。这些信息对于实时监控作业的运行状况以及进行作业调优非常有帮助。 此外,YARN客户端还可以用于管理作业的生命周期。用户可以使用YARN客户端来杀死正在运行的作业或取消已提交但未开始执行的作业。这对于当用户不再需要某个作业时或出现意外情况需要断作业时非常有用。 总之,Hadoop YARN客户端是Hadoop生态系统负责与YARN资源管理器通信的关键组件。它提供了作业的提交、监控和管理的功能,帮助用户实现高效的分布式计算任务。 ### 回答3: Hadoop-YARN-Client是Hadoop生态系统的一个组件,它是Hadoop资源管理器(YARN)的客户端库。YARNHadoop的第二代资源管理系统,它的目的是为集群的各个工作负载提供资源调度和管理服务。 Hadoop-YARN-Client的作用是允许用户通过编程方式与YARN交互,以便向集群提交应用程序,并监控和管理它们的执行。通过Hadoop-YARN-Client,用户可以以编程方式与YARN的应用程序客户端接口(API)进行交互,完成下列任务: 1. 提交应用程序:用户可以使用Hadoop-YARN-Client将一个应用程序提交给YARN。提交应用程序时,需要指定应用程序的类型、优先级、所需资源等信息,并将应用程序的代码和依赖项打包成一个本地或分布式的Jar文件。 2. 监控应用程序:一旦应用程序被提交到YARN,用户可以使用Hadoop-YARN-Client监控应用程序的执行情况。用户可以查询应用程序的状态、进度和资源使用情况等信息。 3. 管理应用程序:用户可以使用Hadoop-YARN-Client管理应用程序的执行。例如,用户可以请求YARN增加或减少分配给应用程序的资源,或者终止应用程序的执行。 总之,Hadoop-YARN-Client是Hadoop生态系统YARN交互的关键组件之一。它为用户提供了一种便捷的方式来提交、监控和管理在YARN上执行的应用程序,让用户能够更好地利用集群资源和进行任务调度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值