0 YARN中实体
资源管理者(resource manager, RM)
长时间运行的守护进程,负责管理集群上资源的使用节点管理者(node manager, NM)
长时间运行的守护进程,在集群的所有节点上运行,负责监视容器容器(container)
在受限的资源集合(内存、CPU等)下执行应用相关的进程
1 YARN应用
1.1 运行
(1) 客户端联系RM,请求运行应用master(application master, AM)进程。
(2) RM定位可用NM,并在NM上启动容器并在容器中加载AM。
AM启动后执行的事项依赖于应用,可以是在容器中执行计算并直接将结果返回给客户端,或者
(3) 向RM请求更多的容器。
(4) 组织、安排、启动容器,执行分布式计算。
1.2 资源请求
申请一些容器的资源请求可以制定每个容器上所需的计算资源,包括内存、CPU等,同时也可以指定容器所需满足的局部性约束。
局部性是保证在执行分布式数据处理算法时带宽高效利用的关键。
YARN应用任意时刻均可以执行资源请求。Spark采用预先申请固定数量的资源方式,而MapReduce在map阶段预先申请固定数量的资源,在reduce阶段即时申请资源。
1.3 应用生命周期
YARN应用可以是短时的(几秒钟),也可以是长时间运行的(几天甚至几个月)。
将用户运行的作业(job)映射为应用的方式:
(1) 为每个用户作业运行一个应用,MapReduce采用的方式;
(2) 为每个工作流或用户会话作业运行一个应用,Spark采用这种方式;
(3) 运行单个长时间运行的应用,被不同的用户作业共享,Apache Slider、Impala采用这种方式。
1.4 构建YARN应用
YARN项目中distributed shell应用可以作为如何编写YARN应用的示例。
一些项目可用于简化YARN应用的开发,如Apache Slider、Apache Twill等。
2 YARN中的调度
2.1 可用调度选项
YARN中有三类调度器可用:FIFO、Capacity和Fair。
运行一个长时间作业和一个段时间作业时各调度器的集群利用率比较图:
FIFO
FIFO调度器将应用存放在队列中,按应用提交的顺序执行应用。
队列头的应用申请的资源被首先分配,待其执行完毕后,下一个应用申请的资源被分配。
Capacity
Capacity调度器开辟出为小作业使用的专用队列。
Fair
Fair调度器在所有运行作业之间动态平衡资源分配。
2.2 Capacity调度器
Capacity调度器调度器允许在组织结构内共享Hadoop集群资源,每个组织部门占用整个集群资源的固定一部分。
Capacity调度器支持队列弹性(queue elasticity),运行作业申请的资源查过预先指定的队列容量、且其他队列中有闲置的容量,可以申请成功;Capacity调度器不支持抢占(preempt),在占有当前队列容量的容器结束后返回资源后这部分容量才可用。
Capacity调度器使用的配置文件为capacity-scheduler.xml
。Capacity调度器完整的说明和配置项见Hadoop: Capacity Scheduler.
为应用选择队列依赖与应用。在MapReduce中,可以设置属性mapreduce.job.queuename
指定为期望使用的队列名称,该属性未配置时,使用默认队列default
。
一个配置示例
队列层次:
root
├── dev
│ ├── eng
│ └── science
└── prod
capacity-scheduler.xml:
<configuration>
<!-- 指定子队列 -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>prod,dev</value>
</property>
<!-- 指定子队列dev的子队列 -->
<property>
<name>yarn.scheduler.capacity.root.dev.queues</name>
<value>eng,science</value>
</property>
<!-- 指定子队列prod的容量 -->
<property>
<name>yarn.scheduler.capacity.root.prod.capacity</name>
<value>40</value>
</property>
<!-- 指定子队列dev的容量 -->
<property>
<name>yarn.scheduler.capacity.root.dev.capacity</name>
<value>10000</value>
</property>
<!-- 指定子队列dev的最大容量 -->
<property>
<name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
<value>75</value>
</property>
<!-- 指定子队列dev.eng的容量 -->
<property>
<name>yarn.scheduler.capacity.root.dev.eng.capacity</name>
<value>50</value>
</property>
<!-- 指定子队列dev.science的容量 -->
<property>
<name>yarn.scheduler.capacity.root.dev.science.capacity</name>
<value>50</value>
</property>
</configuration>
2.3 Fair调度器
Fair调度器在所有运行应用之间动态平衡资源分配。
激活Fair调度器的方式是在yarn-site.xml
中定义:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
Fair调度器的配置文件为分配文件fair-scheduler.xml
,该文件的名称可以使用yarn.scheduler.fair.allocation.file
属性配置修改。
一个配置示例
Fair调度器完整的说明和配置项见Hadoop: Fair Scheduler。
队列层次与上一节中队列层次相同,
fair-scheduler.xml:
<allocations>
<!-- 指定默认的队列调度策略 -->
<defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<!-- 子队列prod -->
<queue name="prod">
<weight>40</weight><!-- 队列权重 -->
<schedulingPolicy>fifo</schedulingPolicy><!-- 队列中调度策略 -->
</queue>
<!-- 子队列dev -->
<queue name="dev">
<weight>60</weight>
<!-- 指定子队列eng和science -->
<queue name="eng" />
<queue name="science" />
</queue>
<!-- 应用放置到各队列的策略 -->
<queuePlacementPolicy>
<rule name="specified" create="false"/><!-- 应用中指定了队列 -->
<rule name="primaryGroup" create="false" /><!-- 与用户所属UNIX组名称相同的队列 -->
<rule name="default" queue="dev.eng"/><!-- 默认行为 -->
</queuePlacementPolicy>
</allocations>
Fair调度器也可以指定队列层次,每个队列可以采用不同的调度策略。
Fair调度器使用一个基于规则的系统,以确定如何将应用放置在队列中。
Fair调度器支持抢占(preemption)。抢占允许调度器直接杀死使用了超出其公平共享资源的队列中的容器,以保证其他队列能够获取公平共享的资源。