Hadoop YARN


Hadoop YARN


Apache YARN (Yet Another Resource Negotiator) 是 Hadoop 集群资源管理系统。YARN 由 Hadoop 2 引入以改进 MapReduce 实现,但它是通用的,足以支持其他分布式计算模型。


YARN 为请求提供 API 并与集群资源共同工作,但这些 API 通常不是由用户代码直接使用的。相反,用户使用由其他分布式计算框架提供的更高级别的 API 来写用户代码,这些框架本身建立在 YARN 之上,并对用户隐藏了资源管理的细节。下图演示了一些分布式计算框架(MapReduce, Spark, 等等)作为 YARN application 运行在集群计算层(YARN) 和集群存储层(HDFS and HBase).

                +---------------+    +---------------+    +---------------+    +---------------+
                |                |    |                |    |                |    |                |
    Application |    MapReduce    |    |    Spark        |    |    Tez            |    |    ...            |
                |                |    |                |    |                |    |                |
                +---------------+     +---------------+    +---------------+    +---------------+
                +---------------------------------------------------------------------------+
                |                                                                            |
    Compute        |                            YARN                                            |
                |                                                                            |
                +---------------------------------------------------------------------------+
                +---------------------------------------------------------------------------+
                |                                                                            |
    Storage        |                        HDFS and HBase                                        |
                |                                                                            |
                +---------------------------------------------------------------------------+

还有一层的应用程序是建立在上图所示的框架上, Pig, Hive, 以及 Crunch 是运行于 MapReduce, Spark, or Tez (or on all three) 之上的处理框架的例子,
并且不直接与 YARN 交互。



*
*
*

1 剖析 YARN 应用程序的运行 (Anatomy of a YARN Application Run)
------------------------------------------------------------------------------------------------------------------------------------------------
YARN 通过两种长期运行的守护进程提供其核心服务:一个资源管理器(resource manager, one per cluster) 管理集群资源的使用; 运行于集群内所有节点上的
节点管理器(node managers) 用于启动和监视容器(container). 一个容器使用一系列受限的资源(内存,CPU,等)执行应用程序特定的进程。依赖于 YARN 是如何
配置的,一个容器可能是一个 Unix 进程,或者一个 Linux cgroup.

在 YARN 上运行一个应用程序,客户端联系 resource manager 并请求它运行一个 application master 进程。 resource manager 找到一个能够在一个容器内运行
application master 的 node manager. 一旦 application master 运行起来它到底能做什么完全取决于应用程序。它可以简单地在它运行的容器内运行一个计算并
将结果返回给客户端。或者,它从 resource manager 请求更多的容器,并使用它们运行一个分布式计算。后面就是 MapReduce YARN 应用程序做的事情了。
    
YARN 本身并不为应用程序各个部分(client, master, process) 之间提供任何彼此通信的方法。很多重要的 YARN 应用程序使用一些远程通信机制(例如 Hadoop 的
RPC 层)来将状态更新和结果传递回给客户端,但这些是应用程序特定的。


    1. 资源请求 (Resource Requests)
    --------------------------------------------------------------------------------------------------------------------------------------------
    YARN 有一个灵活的模型来服务于资源请求。对一组容器的请求可以表示为每一个容器请求的计算资源的数量(memory and CPU),此外,对容器的本地化约束也
    在请求中。

    本地化是确保分布式数据处理算法高效使用带宽的关键,因此 YARN 允许应用程序为它请求的容器指定本地化约束。本地化约束可用于请求一个容器在特定的节点
    或机架上,或集群的任何位置上。

    有时本地化约束不满足,这种情况下或者没有分配可用,或者,可选地,可以将约束放宽松。例如,一个特定的节点被请求了,但不可能在其上启动一个容器(
    因为其他容器正在上面运行),然后 YARN 会试着从同一机架的其他节点启动容器,或者,如果这种方式不可能,在集群内的任何节点启动。
    
    一般场景下,启动一个容器进程来处理一个 HDFS 块(比如运行一个 MapReduce map 任务),应用程序会在存储数据块的三个复本的节点中请求一个容器,或者在
    存储复本的机架其中的一个节点上,或者,如果也失败了,在集群内任何一个节点上。

    一个 YARN 应用程序可以在它运行的任何时候进行资源请求。例如,一个应用程序可以预先进行所有的请求,或者,它可以利用一个更动态的方法借以更动态地
    请求资源以满足应用程序变化的需要。
    
    Spark 使用第一种方法,一开始就在集群上请求固定数量的执行器。 MapReduce, 在另一方面,由两个阶段: map 任务的容器是预先请求的,但 reduce 任务
    容器会晚些启动。另外,如果任何任务失败了,会请求另外添加的容器这样失败的任务能被重新运行。
    

    2. 应用程序存活期 (Application Lifespan)
    --------------------------------------------------------------------------------------------------------------------------------------------
    YARN 应用程序的存活期可能具有戏剧性的变化:从存活最短的只有几秒的应用程序到长期运行的应用程序可以运行几天甚至几个月。不是看应用程序运行多长
    时间,将应用程序按它们如何映射到用户运行的作业来分类更有用。最简单的情景是一个应用一个用户作业,这是 MapReduce 使用的方法。
    
    第二种模型是每个工作流或多个作业(可能彼此不相关)的一个用户会话运行一个应用程序。这种方式可能比第一种更高效,因为容器可以在作业间被重用,也可能
    在作业间缓存中间数据。 Spark 是使用这种模式的一个例子。
    
    第三种模型是一个长期运行的应用程序有不同的用户共用。这样的一个应用程序经常作为某类协调器角色。例如, Apache Slider 有一个长期运行的程序控制
    集群上其他应用程序的启动。这种方式也被 Impala 用于提供一个代理应用程序,Impala 守护进程通过与它通信来请求集群资源。一直在运行(always on) 的
    application master 意味着用户对查询有非常低延迟(very low-latency) 的响应。因为避免了启动一个新的 application master 的开销。
    
    
    3. 构建 YARN 应用程序 (Building YARN Applications)
    --------------------------------------------------------------------------------------------------------------------------------------------    
    从头开始写一个 YARN 应用程序是非常复杂的,但大多数情况下没必要这样做,因为一般使用现有的应用程序可以符合我们的要求。例如,如果对运行一个有向
    非循环图(directed acyclic graph, DAG)的作业感兴趣,则 Spark 或 Tez 是适用的;或者对于流式处理,Spark, Samza, or Storm 可以工作。
    
    有多个项目可用于简化构建 YARN 应用。 Apache Slider, 使得在 YARN 上运行现有的分布式应用程序称为可能。用户可以在集群上运行一个应程序(such as
    HBase)他们自己的实例,独立于其他用户,意味着不同的用户可以运行同一应用程序的不同版本。 Slider 提供了可以改变应用程序运行的节点数量的控制,
    以及可以挂起然后恢复运行中的应用程序。
    
    Apache Twill 类似于 Slider, 但它额外增加了为 YARN 上开发分布式应用程序提供了一个简单的编程模型。 Twill 允许定集群进程作为一个 Java Runnable 的
    扩展,然后在集群的 YARN 容器中运行它们。 Twill 也提供了实时日志(real-time logging, log events from runnables are streamed back to the client)
    以及命令消息(command messages, sent from the client to runnables)的支持。
    
    这些选项都不够充分的情况下 ———— 这样的应用程序有复杂的调度需求 ———— 则可以参考 distributed shell 应用程序,YARN 项目的一部分,作为如何写 YARN
    程序的例子程序。它演示了如何使用 YARN 的客户端 API 来处理客户端或 Application master 与 YARN 守护进程间通信。
    
    
*
*
*

2 YARN 与 MapReduce 1 比较 (YARN Compared to MapReduce 1)
------------------------------------------------------------------------------------------------------------------------------------------------    
The distributed implementation of MapReduce in the original version of Hadoop (version 1 and earlier) is sometimes referred to as “MapReduce 1”
to distinguish it from MapReduce 2, the implementation that uses YARN (in Hadoop 2 and later).

All four combinations are supported: both the old and new MapReduce APIs run on both MapReduce 1 and 2.

在 MapReduce 1, 有两种类型的守护进程(daemon) 控制作业的执行过程:一个 jobtracker 和一个或多个的 tasktracker. jobtracker 协调所有的作业在系统上运行,
通过调度任务运行在 tasktracker 上。 tasktracker 运行作业并发送进程报告给 jobtracker, 对于每个作业的整个进度保持一个记录。如果一个任务失败了,
jobtracker 可以重新调度它到一个不同的 tasktracker 上运行。

在 MapReduce 1, jobtracker 同时兼顾作业调度和任务进度监控(保持跟踪任务,重启失败或很慢的任务,以及做任务簿记,例如维护计数器)。相反,在 YARN 中,
这些责任由两个分开是实体处理: resource manager 和 application master(每个 MapReduce 作业一个)。 jobtracker 也负责为完成的作业存储作业历史,尽管
可以运行一个作业历史服务器作为一个单独的守护进程来卸下 jobtracker 的负荷。在 YARN 中,相同的角色是 timeline server, 用于存储应用程序历史。

YARN 中,与 tasktracker 对应的等价物是 node manager.
            
            A comparison of MapReduce 1 and YARN components
            
    +===============+===========================================================+
    | MapReduce 1    |            YARN                                            |
    +---------------+-----------------------------------------------------------+
    | Jobtracker    | Resource manager, application master, timeline server        |
    +---------------+-----------------------------------------------------------+
    | Tasktracker    | Node manager                                                |
    +---------------+-----------------------------------------------------------+
    | Slot            | Container                                                    |
    +---------------+-----------------------------------------------------------+
    

YARN 设计用来解决 MapReduce 1 的一些限制。使用 YARN 的优势包括如下几点:

    
    □ 可扩展性 (Scalability)
    -------------------------------------------------------------------------------------------------------------------------------------------
    YARN 能运行比 MapReduce 1 更大的集群。由于 jobtracker 必须兼顾管理作业和任务的事实,MapReduce 1 在 4000 个节点和 40000 个任务区间遇到可扩展
    性瓶颈(scalability bottlenecks)。 YARN 凭借将 resource manager/application master 分开的体系机构,克服了这些限制:它设计可扩展至 10000 个节点
    和 100000 个任务。    
    
    与 jobtracker 相反,每个应用程序实例 ———— 这里指的是一个 MapReduce 作业 ———— 有一个指定的 application master, 运行于应用程序期间。
    
    
    □ 可用性 (Availability)
    -------------------------------------------------------------------------------------------------------------------------------------------    
    高可用性(High availability, HA) 一般通过复制所需状态信息的方式实现,在服务的守护进程失效时由另一守护进程接管工作来提供服务。然而,大量的迅速
    变化的复杂状态在 jobtracker 的内存中(例如,每个任务状态几秒内就更新),使应用高可用性 到 jobtracker 服务非常困难。
    
    在 YARN 中,将 jobtracker 的责任分开为 resource manager 和 application master, 使得服务的高可用性变成一个分别攻克的问题(a divide-andconquer
    problem): 为 resource manager 提供 HA, 然后为 YARN application 提供 HA (基于每应用程序的方式 —— on a per-application basis). 事实上, Hadoop 2
    对 resource manager 和 MapReduce 作业的 application master 都支持 HA.  
    

    □ 效用 (Utilization)
    -------------------------------------------------------------------------------------------------------------------------------------------        
    MapReduce 1 中,每个 tasktracker 配置为一个静态分配的固定大小(fixed-size) 的 slot, 在配置时分成 map slots 和 reduce slots. 一个 map slot 只能
    用于运行一个 map 任务,而一个 reduce slot 只能用于运行一个 reduce 任务。
    
    在 YARN 中,一个节点管理器管理一个资源池(a pool of resources), 而不是一个固定数量的指定的 slots. 运行在 YARN 上的 MapReduce 不会遇到这种情况:
    一个 reduce 任务必须等待因为在集群上只有 map slots 可用,这在 MapReduce 1 是可能发生的。如果运行任务是资源可用,则应用程序就会使用它们。
    
    此外, YARN 中的资源是精细粒度的,这样,应用程序就可以请求它所需的资源,而非一个不可分的 slot, 那对一个特定的任务来说,可能太大(浪费资源)或
    太小(导致失败)。
    
    
    □  多重任务处理 (Multi-tenancy)
    -------------------------------------------------------------------------------------------------------------------------------------------        
    在某些方面, YARN 的最大优点是它将 Hadoop 开放给其他类型的分布式应用,远远超出了 MapReduce. MapReduce 只是 YARN 众多应用的其中之一。
    
    用户甚至可以在同一个 YARN 集群上运行不同版本的 MapReduce, 这使得升级 MapReduce 的过程更加可管理。(注意, MapReduce 的一些组件,例如作业历史
    服务器和 shuffle handler, 以及 YARN 本身,仍需跨集群升级)。
    
    
    
*
*
*

3 YARN 中调度 (Scheduling in YARN)
------------------------------------------------------------------------------------------------------------------------------------------------        
在理想世界中, YARN 应用程序发出的请求应该立刻给予。然而,在现实世界中,资源是有限的,并且在一个繁忙的集群上,应用程序经常需要等待一些资源请求
满足要求。这是 YARN 调度器(scheduler) 的工作,根据定义的策略为应用分配资源。调度通常是个难题,而且没有一个所谓最好的策略(no one "best" policy),
这就是为什么 YARN 提供了调度器的选择和可配置的策略。


    1. 调度器选项 (Scheduler Options)
    --------------------------------------------------------------------------------------------------------------------------------------------
    YARN 中有三个可用的调度器:FIFO, Capacity, 以及 Fair 调度器。
    
    FIFO 调度器把应用程序放入一个队列中并按它们提交的次序运行(first in, first out). 队列中第一个应用的请求首先分配,一旦它的请求满足了,队列中下
    一个应用程序提升上来,以此类推。
    
    FIFO Scheduler 有理解简单和不需要任何配置的优点,但不适合共用的集群。大型应用会使用集群上所有的资源,因此每个应用必须依次等待。在一个共用的集群
    上,使用 Capacity Scheduler 或 Fair Scheduler 更好。这两个调度器都允许长时间运行的作业(long-running jobs)以一个适时的方式完成,然而,仍然允许
    用户并发运行更小的应用以合理的时间得到运行结果。
    
    在 FIFO Scheduler 下,小作业被阻塞直到大作业完成。
    
    使用 Capacity Scheduler, 一个独立的专用队列允许小作业只要一提交就启动,然而这以整个集群利用率为代价,因为队列容量为队列中的作业保留。这意味着
    大作业结束比使用 FIFO Scheduler 时间晚。
    
    使用 Fair Scheduler, 没有必要保留一定数量的容量,因为它会在所有运行中的作业间动态均衡资源。就在第一个(larger)作业启动之后,只有一个作业正在运行,
    因此它得到集群内所有的资源。当第二个(small) 作业启动时,它被分配集群资源的一半,这样每个作业使用其公平的共用资源。
    
    注意,在第二个作业启动和它收到它的公平共用之间有一个时间上的落后,因为它必须等待第一个作业作为容器使用的资源释放完成。在小作业完成后不再请求
    资源,大作业回来再次使用整个集群容量。整体效果是高的集群效用和及时的小作业完成。
    
    
    2. Capacity Scheduler 配置 (Capacity Scheduler Configuration)
    --------------------------------------------------------------------------------------------------------------------------------------------    
    Capacity Scheduler 允许根据有组织的路线共用一个 Hadoop 集群,通过为每一个组织(organization)分配整个集群一部分确定的容量。每个组织由一个特定的
    队列建立,配置为使用整个集群容量的百分数。队列可以更进一步按层级的形式划分,允许每个组织在不同的组用户间共用集群的限额。在一个队列内,应用使用
    FIFO 调度。
    
    一个作业不能使用比它队列容量更多的资源。然而,如果队列中有超过一个的作业并且还有闲置的可用资源,那么 Capacity Scheduler 可以分配这些剩余的资源
    给队列中的作业,甚至会导致队列的容量超出。这种行为被称为队列弹性(queue elasticity)。
    
    在正常操作中,Capacity Scheduler 不通过强制杀死来抢占容器,因此如果由于缺乏需求而使队列低于容量,并且随后需求增加,队列只有在资源从其他队列作为
    容器释放完成时才会回收容量。可以通过使用一个最大容量配置队列来缓解这种现象,这样它们就不会吃掉其他队列的容量太多。这当然会牺牲队列弹性,因此,
    应该通过测试和错误找出一个合理的权衡。
    
    假设一个队列的层次结构如下所示:
    
        root
        ├── prod
        └── dev
            ├── eng
            └── science
        
    
    下面显示的是为此层次结构定义的 Capacity Scheduler 配置文件样例,称为 capacity-scheduler.xml。 它在跟队列(root)下定义了两个队列 prod 和 dev, 分别
    具有 40% 和 60% 的容量。注意,特定队列的配置通过设置配置属性的形式:
    
        yarn.scheduler.capacity.<queue-path>.<sub-property>
        
    <queue-path> 是队列的层次路径(点分隔), 例如 root.prod
    
        // A basic configuration file for the Capacity Scheduler
        <?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 队列。 当 prod 队列空闲时, dev 队列不会占用所有的集群资源,它的最大容量设置为 75%。换句话说, prod 队列
    总是有 25% 的可用集群容量可以立即使用。因为没有对其他队列设置最大容量,在 eng 或 science 队列中的作业可以使用全部的 dev 队列容量(多达 75% 的集群容量),
    或者,实际上, prod 队列可以使用整个集群。
    
    除了配置队列层次结构和容量,还有一些设置,控制一个用户能使用的或一个应用能被分配的最大资源数量,同一时刻能运行多少个应用程序,以及队列上的 ACL
    
    
        队列放置 (Queue placement)
        ----------------------------------------------------------------------------------------------------------------------------------------
        指定应用程序放置到哪一个队列中的方法是特定于应用程序的。例如,在 MapReduce 中,可以设置属性 mapreduce.job.queuename 值为想要使用的队列的
        名称。如果队列不存在,会在提交时获得一个错误。如果没有队列指定,应用将被放到名称为 default 的队列中。
        
            WARNING
            --------------------------------------------------------------------------------------------------------------------------------
            对于 Capacity Scheduler, 队列的名称应为层次结构名称的最后一个部分,因为全部的层次结构名称是不可识别的。因此,对于之前的例子配置,
            prod and eng are OK, but root.dev.eng and dev.eng do not work.
    
    
    
    3. Fair Scheduler 配置 (Fair Scheduler Configuration)
    --------------------------------------------------------------------------------------------------------------------------------------------        
    Fair Scheduler 试图分配资源以便所有运行的应用获得相同的共用(shared)资源。然而,公平共用实际上也是工作在队列之间。
    
    为了理解资源如何在队列之间共用,假设两个用户 A 和 B, 每个用户有他们自己的队列。 A 启动一个作业,它被分配到所有可用的资源因为没有来自于 B 的
    需求。然后在 A 的作业还在运行时, B 启动一个作业,过一小会儿之后。每个作业运行一半的资源。现在如果 B 启动第二个作业,此时其他作业仍在运行,它
    将与 B 的其他作业共用资源,这样,每个 B 的作业将会拥有四分之一的资源,而 A 将继续拥有一半的资源。结果是资源在用户之间公平共用。
    
    
        启用 Fair Scheduler (Enabling the Fair Scheduler)
        ----------------------------------------------------------------------------------------------------------------------------------------    
        调度器的使用通过设置 yarn.resourcemanager.scheduler.class 来确定。默认使用 Capacity Scheduler, 但可以通过在 yarn-site.xm 文件中设置属性
        
        yarn.resourcemanager.scheduler.class
        
        为调度器的完全限定类名来改变:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
    
    
    
        队列配置 (Queue configuration)
        ----------------------------------------------------------------------------------------------------------------------------------------    
        Fair Scheduler 配置使用一个名为 fair-scheduler.xml 的分配文件,从类路径加载。(文件名可以通过设置属性 yarn.scheduler.fair.allocation.file
        改变) 在分配文件不存在的情况下,调度器按之前的描述操作:每一个应用被放到一个队列用户之后命名,并且当用户提交它们的第一个应用时动态创建队列
        
        每队列(Per-queue)配置在分配文件中指定。这允许配置层次结构的队列就像 Capacity Scheduler 支持的那样。例如,可以使用下面的分配文件定义 prod
        和 dev 队列就像我们为 Capacity Scheduler 所做的那样。
    
            // An allocation file for the Fair Scheduler
            <?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.
    
        队列可以有 weight, 用于公平共用计算。在这个例子中,prod 和 dev 之间划分为 40:60 的比例认为集群分配是公平的。 eng 和 science 队列没有指定
        weight, 因此它们被均匀划分。weight 不与百分数完全相当,即便本例中使用的数值加起来为 100 是为了简单的缘故。可以为 prod 和 dev 指定 weight 值为
        2 和 3 实现相同的队列 weighting.
    
            NOTE:
            ----------------------------------------------------------------------------------------------------------------------------------------
            当设置 weight 时,记住要考虑默认队列和动态创建的队列(such as queues named after users).这些没有在分配文件中指定,但仍有 weight 值为 1
    
        
        队列可能有不同的调度策略。队列的默认策略可以被设置在顶级元素(the top-level defaultQueueSchedulingPolicy element), 如果它被忽略了,使用公平调度。
        不管它的名称,Fair Scheduler 在队列上也支持 FIFO 策略。
        
        对一个特定队列的策略可以使用该队列的 schedulingPolicy 元素覆盖。在本例情景中, prod 队列使用 FIFO 调度因为我们向要每个生产作业连续运行并以尽
        可能短的时间完成。注意,公平共用仍然用于在 prod 和 dev 队列间划分资源,也在 eng 和 science 队列之间划分资源。
        
        队列也可以通过最少资源和最多资源配置,以及最多运行的应用程序。
    
    
        队列放置 (Queue placement)
        ----------------------------------------------------------------------------------------------------------------------------------------    
        Fair Scheduler 使用基于规则的系统(a rules-based system) 来确定一个应用放置到哪个队列中去。 queuePlacementPolicy 元素包含一个规则列表,
        每一个按次序尝试直到一个匹配放生。第一个规则, specified, 把一个应用放置到它指定的队列中,如果没有指定的,或者指定的队列不存在,则这条规则
        不匹配并尝试下一个规则。 primaryGroup 规则尝试使用用户的 primary Unix group 把应用程序放置到一个队列中,如果没有这样的队列,不是创建它,
        而是尝试下一条规则。 default 规则是一个 catch-all 并且总是把应用放置到 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, 这样应用就会被放置的默认队列中,而不是
        一个每用户的队列中(per-user queue)。另外,yarn.scheduler.fair.allow-undeclared-pools 应该设置为 false, 这样用户就不能随意地创建队列。
    
    
        优先抢占 (Preemption)
        ----------------------------------------------------------------------------------------------------------------------------------------    
        当作业被提交到一个繁忙集群上的一个队列时,作业不能启动,直到资源从集群上已经运行的作业释放。为了使一个作业取得的启动时间更加的可预期,
        Fair Scheduler 支持优先抢占(preemption)。
        
        优先抢占允许调度器杀掉正在运行中的,使用比它们的共用资源更多资源的队列容器,这样,资源能够分配给公平共用下的队列。注意,优先抢占降低了整个
        集群的效率,因为被终止的容器需要被重新运行。
        
        优先抢占通过设置 yarn.scheduler.fair.preemption 值为 true 来全局启用。有两个相关的超时设置:一个为最小共用,另一为公平共用,两者都指定为秒。
        默认地,超时没有设置,因此需要至少设置一个来允许容器优先抢占。
        
        如果一个队列等待长达 minimum share preemption timeout 的时间而没有收到最小 guaranteed share, 调度器可以抢占其他容器。默认超时
        是对所有队列的,通过分配文件的 defaultMinSharePreemptionTimeout 顶级元素,也可以基于 per-queue 通过为一个队列设置 minSharePreemptionTimeout
        元素。
        
        同样地,如果一个队列一直保持在低于它的公平共用一半以下长达 fair share preemption timeout 的时间,则调度器可以抢占其他容器。默认的超时设置
        应用于所有队列,通过在分配文件中的顶级元素 defaultFairSharePreemptionTimeout 设置,基于每队列的超时通过在队列上设置
        fairSharePreemptionTimeout 元素。阈值也可以从其默认的 0.5 改变,通过设置 defaultFairSharePreemptionThreshold 和
        fairSharePreemptionThreshold (per-queue)。
        
            
    
    4. 延迟调度 (Delay Scheduling)
    --------------------------------------------------------------------------------------------------------------------------------------------        
    所有的 YARN 调度器都设法重视本地化请求。在一个繁忙的集群上,如果一个应用请求一个特定的节点,这是一个好机会,在请求的同时有其他容器正该节点上
    运行。操作的明显过程是立刻放宽本地化请求并在同一机架上分配一个容器。然而,实际经验是等待一个小段时间(不会超过几秒钟)可以显著地提升在请求的
    节点上分配一个容器的机会,并由此提升集群效率。这个特性被称为延迟调度 (delay scheduling), 并被 Capacity Scheduler 和 Fair Scheduler 都支持。
    
    在 YARN 集群上每个 node manager 定期向 resource manager 发送一个心跳请求 ———— 默认情况,每秒一个。心跳携带有关 node manager 的正在运行中的容
    器和新容器可用资源的信息,因此,每一个心跳是一个潜在的为应用程序运行一个容器的调度机会(scheduling opportunity)。
    
    当使用延迟调度,调度器不是简单地使用它就收到的第一个调度机会,而是在放宽本地化约束和获取下一个调度机会之前等到一个给定的最大数量的调度机会出现
    
    对于 Capacity Scheduler, 延迟调度通过设置 yarn.scheduler.capacity.node-locality-delay 为一个正整数配置,表示为在放宽节点约束来匹配同一机架内
    任何节点之前准备错过的调度机会的数量。
    
    Fair Scheduler 也使用调度机会数量来确定延迟,然而它表示为集群大小的百分比。例如,设置 yarn.scheduler.fair.locality.threshold.node 的值为 0.5
    意味着在接受同一机架另一个节点之前,调度器应该等待直到集群中半数的节点已表现调度机会。有个对应的属性
    yarn.scheduler.fair.locality.threshold.rack 用于设置另一个机架可接受而不是请求的那个机架的阈值。
    
    
    5. 优势资源公平 (Dominant Resource Fairness)
    --------------------------------------------------------------------------------------------------------------------------------------------
    当只有一种资源类型要调度时,例如内存,则 capacity 或 fairness 的概念很容易确定。如果两个用户运行应用,可以评测每一个应用使用内存的数量来比较
    两个应用。然而,当有多种资源类型使用时,事情就复杂了。如果一个用户的应用要求很多 CPU 但较少的内存,而另一个要求较少的 CPU 但需要大量的内存,
    这两个应用如何比较呢?
    
    YARN 中调度器处理这个问题的方法是查看每个用户的优势(dominant)资源并使用它来评测集群使用。这种方法称为优势资源公平(Dominant Resource Fairness,
    or DRF for short).
    
    假设一个集群有总共 100 个 CPU 和 10 TB 的内存,应用 A 请求(2 CPUs, 300 GB)的容器,应用 B 请求 (6 CPUs, 100 GB)的容器。A 的请求是:
    (2%, 3%) of the cluster, 因此内存是占优势的因为它的比例(3%) 比 CPU 的(2%) 大。B 的请求是(6%, 1%), 因此 CPU 是占优势的。由于 B 的容器在优势资源
    上请求两倍于 A 的优势资源(6% versus 3%), 在公平共用之下它会被分配集群半数资源的容器。
    
    默认情况下,没有使用 DRF, 因此在资源计算期间,只考虑了内存,而 CPU 被忽略。 Capacity Scheduler 可以配置使用 DRF, 通过在 capacityscheduler.xml
    中设置:
    yarn.scheduler.capacity.resource-calculator 的值为 org.apache.hadoop.yarn.util.resource.DominantResourceCalculator
    
    对于 Fair Scheduler, DRF 可以通过在分配文件中设置顶级元素 defaultQueueSchedulingPolicy 的值为 drf 来启用。
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
   

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值