理想情况下,YARN 应用发出资源请求时应该立刻给予满足。但是在实际生产环境中资源是有限的,
在一个繁忙的集群上,一个应用经常需要等待才能分配到所需要的资源。
YARN 调度器的工作就是根据既定策略为应用能够分配资源。调度是一个难题,
并没有一个所谓 “最好” 的调度策略,在 YARN 提供了多种调度器和可配置策略供我们选择
YARN 中有三种调度器可用:FIFO 调度器(FIFO Scheduler),容量调度器(Capacity Scheduler)
和公平调度器(Fair Scheduler)。
下面来详细介绍一下这三种调度方式
FIFO Scheduler(FIFO 调度器):
FIFO 调度器将所有提交的应用放置在一个队列中,按照提交的顺序(先进先出)运行应用。
首先为队列中的第一个应用的请求分配资源,当第一个应用的请求被满足后在依次为队列中的下一个应用服务。
FIFO 调度器的优点是,简单易懂,不需要任何配置,但是不适合共享集群。大的应用会占用集群中的所有资源,
所以在队列中的所有应用必须等待知道轮到自己运行。在一个共享集群中,更适合使用容量调度器或者公平调度器。
这两种调度器都允许长时间运行的作业能够及时完成,同时也允许正在进行较小的临时查询的用户能够在合理的
时间内能够及时运行并且得到返回结果。
Capacity Scheduler(容量调度器):
容量调度器允许多个组织共享一个 Hadoop 集群,每个组织可以分配到全部集群资源的一部分。
每个组织对的应用被分配到一个专门的队列,每个队列被配置为可以使用一定的集群资源。队列可以进一步按层次划分,
这样每个组织内的不同用户能够共享该组织队列所分配的资源。在一个队列内,使用 FIFO 调度策略对应用进行调度。
单个作业使用的资源不会超过其队列的资源容量。在队列中有多个作业,并且该队列资源不足时,这时如果集群中
仍有可使用资源,容量调度器可能会将空余的资源分配给队列中的作业,哪怕这样做会超出该队列的资源容量。
这也被称为 “弹性队列” (queue elasticity)。
正常操作时,容量调度器不会通过强行终止作业来抢占容器(container)。因此,如果一队列一开始资源够用,然后随着程序的运行或是需求的增长,资源开始不够用时,那么合格队列就只能等待其他队列释放容器资源。缓解这种情况的方法是,为队列设置一个最大的容量限制,这样这个队列就不会过多的侵占其他队列资源的容量了。当然,这样做是以牺牲队列弹性作为代价的,因此需要不断的尝试和失败中找出一个最合理的配置。
如果属性 yarn.scheduler.capacity.<queue-path>.user-limit-factor 设置为大于一(默认值)时,
那么一个作业可以使用超过其队列容量的资源。
HDP(Ambari) 方式搭建的 Hadoop 集群,默认实现为(容量调度器)
Fair Scheduler(公平调度器):
公平调度器旨在为所有运行的应用公平分配集群资源。接下来解释资源是如何在队列之间公平共享的。
想象两个用户 A 和 B,分别拥有自己的队列。当 A 启动一个作业,在 B 没有需求是 A 用户
会分配到全部可用资源:当 A 的作业仍在运行是 B 启动一个作业,一段时间后,按照我们先前看到的
方式,每个作业都用到了集群中一般的资源。这时,如果 B 启动第二个作业并且其他作业仍在运行(A作业和B作业),
那么 B 启动的第二个作业将和 B 启动的第一个作业共享资源,也就是说 B 的每个作业占用四分之一的集群资源,
而 A 用户的作业仍然占用一半的集群资源。实现了资源在用户之间的公平共享。
CDH 方式搭建的 Hadoop 集群,默认实现为(公平调度器)
Delay Scheduler (延迟调度):
所有的 YARN 调度器都试图以本地请求为重。在一个繁忙的集群上,如果一个应用请求某个节点,
那么极有可能此时有其他容器正在该节点上运行。显而易见的处理是,放宽本地性需求,在同一机架中分配一个容器。
然而,通过时间发现,此时如果等待一小段时间(不超过几秒),能够戏剧性的增加在所请求的节点上分配到一个容器的
机会,从而可以提高集群的效率。这个特性称之为延迟调度。容量调度器和公平调度器都支持延迟调度。
当使用延迟调度是,调度器不会简单的使用他收到的第一个调度机会,而是等待设定的最大数目的调度机会发生,然后
才放宽本地性限制并接受下一个调度机会。
以上几种调度方式相关的配置不做过多的描述,有兴趣的同学可以查看相关文档。
网友评论