Hadoop权威指南 第4章 关于YARN

it2025-06-07  1

第4章 关于YARN

YARN运行机制资源请求 YARN中的调度调度选项容量调度器配置公平调度器配置 YARN(Yet Another Resource Negotiator)是hadoop的集群资源管理系统。YARN被引入Hadoop2,最初是为了改善MapReduce的实现,但它具有足够的额通用性,同样可以支持其他的分布式计算模式。

图:YARN应用 YARN提供请求和使用集群资源的API,但这些API很少直接用于用户代码。用户代码中用的是分布式计算框架提供的更高层API,这些API简历在YARN之上且向用户隐藏了资源管理细节。 还有一些应用时间里在上图所示框架之上,如Pig、Hive、Crunch都是运行在MapReduce、Spark、Tez之上的处理框架。

YARN运行机制

YARN通过两类长期运行的守护进程提供自己的核心服务:

资源管理器:resource manager,管理集群上资源的使用节点管理器:node manager,运行在集群所有节点上,能够启动和监控容器container

图:YARN应用的运行机制 为了在YARN上运行一个应用,客户端联系资源管理器,要求它运行一个application master进程。资源管理器找到一个能够在容器中启动application master的节点管理器。application master一旦运行起来后能够做些什么依赖应用本身,可能是简单的运行一个计算并返回结果,也可能如图所示,项资源管理器请求更太多的容器。请求新的容器后,就能够运行一个分布式计算 YARN不会为应用的各部分彼此通信提供任何手段。

资源请求

YARN有一个灵活的资源请求模型,请求多个容器时,除了可以指定每个容器需要的计算资源数量(内存和cpu)还可以指定对容器的本地限制要求。 本地化可以确保计算尽可能的靠近数据,减少集群带宽资源,本地限制可用于申请位于指定节点或机架或集群中任意位置的容器。 本地限制无法满足时,要么不分配资源,要么选择放松限制。 通常启动一个容器用于处理map任务时,应用首先会向存储该数据块三个复本的节点或者存储这些复本的机架申请一个节点,如果失败,则申请集群中的任意节点。 YARN应用可以在任意时刻提出资源申请,既可以在最开始提出所有的请求,也可不必一次性申请全部的资源。 Spark就采用了一次性申请的方式,在集群中启动固定数量的执行器。MapReduce采用的动态申请资源的方式,最开始先申请map任务容器,reduce任务容器的启动在map任务完成过后启动。

用户作业之间的映射关系分类:

一个用户作业对应一个应用,MapReduce采用的方式作业的每个工作流或每个用户会哈对应一个应用,容器可以在作业之间重用,并且有可能缓存作业之间的中间数据。Spark采用的这种模式多个用户共享一个长期运行的应用。

YARN中的调度

调度选项

YARN中有三种调度器可用:

FIFO调度器,将应用放置在一个队列中,然后按照提交的顺序运行应用,优点是简单易懂,不需要额外配置,但是不适合共享集群,大的应用会占用集群中所有资源,每个应用必须等待直到轮到自己运行 如图所示,大的应用job1会占用集群中所有资源,job2必须等待直到轮到自己运行容量调度器,有一个独立的专门的任务队列保证小作业已提交就能够启动 由于队列容量是为小作业单独保留,所以这种策略是以整个集群利用率为代价的公平调度器,不需要预留一定量的资源,因为调度器会在所有运行的作业之间动态平衡资源 当一个作业启动时,它是唯一一个作业,而获取集群中的所有资源。当第二个作业启动时,他被分配到集群中一半的资源

容量调度器配置

容量调度器允许多个组织共享一个Hadoop集群,每个组织分配到全部集群资源的一部分,每个组织被配置一个专门的队列,每个队列被配置为可以使用一定的集群资源。在一个队列内部,使用FIFO调度策略对应用进行调度。当一个队列中有多个作业,且资源不够用时,有可能使用其他队列的空闲资源。容器调度器不会通过强制中止进行抢占容器。

图:队列的层次结构

root下有两个队列prod和dev,分别占40%和60%的容量,dev队列进一步分成eng和science两个容量相等的队列 capacity-scheduler.xml

<?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.maxinum-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最大容器设置为75%,因此即使prod队列空闲,dev队列也不会占用全部的集群资源。prod队列即刻能够使用的可用资源比例总是能够达到25%。prod队列可能会占用全部的集群资源。 将应用放到哪个队列取决于应用本身。在MapReduce中,可以通过设置属性mapreduce.job.queuename来指定要用到的队列。

公平调度器配置

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

图:用户队列间的公平共享

两个用户A和B,分别拥有自己的队列。A启动一个作业1,在B没有需求时A会分配到全部的可用资源;当作业1在运行中时,B提交作业2,一段时间后,每个作业占用一半的集群资源。这是如果B提交作业3,那么作业3和作业2共享资源,因此作业2和作业3个占用四分之一的集群资源,最终就是资源在用户之间实现公平共享。

默认是使用容量调度器,如果使用公平调度器,需要将yarn-site.xml文件中的yarn.resourcemanager.scheduler.class设置为公平调度器的完全限定名:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairSchdduler。

通过fair-scheduler.xml对公平调度器进行配置

<?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> <queuePlacementPllicy> <rule name="specified" create="false" /> <rule name="primaryGroup" create="false" /> <rule name="default" create="dev.eng" /> </queuePlacementPllicy> </allocations>

每个队列可以有不同的调度策略。队列的默认调度策略可以通过顶层元素defaultQueueSchedulingPolicy进行设置,默认使用公平调度。 公平调度器也支持队列级别的FIFO策略,以及Dominant Resource Fairness策略。prod队列使用了FIFO调度策略。 queuePlacementPllicy指定了一个应用应该放在哪个队列中,会从第一条规则开始匹配,直到匹配成功。 公平调度器支持资源抢占,允许调度器种植哪些占用资源超过了其公平共享份额的队列的容器。通过yarn.scheduler.fair.preemption设置为true开启抢占功能。

最新回复(0)