《Hadoop权威指南》读书笔记2

Posted by BY KiloMeter on April 10, 2019

第四章 关于YARN

yarn是在hadoop2.x后才出现的,yarn出现把Mapreduce的计算和调度分开。以前MR1把计算和调度一起给实现了,JobTracker负责TaskTracker任务的调度,心跳响应,资源调度,但是在当集群的结点数较多,JotTracker将会成为系统的瓶颈。yarn的出现让MR只需要负责计算部分,减轻也MR的压力。

不仅如此,YARN具有足够的通用性,能够支持其他的分布式计算系统比如Spark。

Yarn提供了一层资源控制的API,把对资源的管理细节封装起来。

Yarn把mapreduce的资源调度和分配任务给分出来之后,带来的好处有以下几点:

1、可扩展性:和Mapreduce1相比,yarn可以使用在更大的集群上,Mapreduce在节点数到达4000时就达到了瓶颈,而yarn可以扩展到将近10000个节点

2、可用性:jobtracker由于内存中存在大量的快速变化的状态(因为jobtracker管理着tasktracker任务的执行,而这些任务每几秒就会进行更新),很难使得jobtracker获得高可用。而yarn中分为了资源管理器和application Master,可用性进行了分而治之,先为资源管理器提供高可用,再为application M啊帅T而提供高可用

3、利用率:Mapreduce1中的资源称为slot,在tasktracker任务开始前,先分配好了mapslot和reduceslot,mapslot只能执行map任务,而reduceslot只能执行reduce任务,如果mapslot用完了,那么其他map任务就只能进入等待状态,哪怕现在有空闲的reduceslot,也无法使用。而yarn对资源的分配更加精细,每个任务可以按需申请资源,而不是一个不可分割的slot。

4、多租户:这个可以说是Yarn出来最大的优点,就是可以让除了Mapreduce以外的计算引擎使用集群的资源。

Yarn中的调度

调度选项

Yarn中调度分为三种:FIFO调度器,容量调度器和公平调度器。

FIFO,first in first out,这里就不解释了,这种调度器的设计比较简单,问题就是小作业的执行必须等大作业执行完后才能执行,很少使用

容量调度器:基于FIFO的问题进行了改进,该调度器有一个独立专门的队列,负责处理小任务,只要小作业一提交就能立刻执行,但是就是这个队列会一直占有资源,即使没有小作业。因此该调度器牺牲了集群的利用率。

公平调度器:结合了上面两者的优点,只有大作业时,全部资源都为该任务服务,如果此时提交了小作业,大作业会分配出部分资源供小作业调度。优点就是既保证了小作业能够快速执行,也提高了集群的利用率。不过就是小作业提交时,并不是立刻就分配资源给小作业的,小作业得等大作业的部分容器使用完释放后才能使用,因此有一定的时间滞后。

容器调度器

该调度器通过capacity-scheduler.xml配置文件,可以配置父子队列关系,设置队列的占有资源和最大占有资源

假设有如下层次结构的队列

该结构配置了两个子队列prod和dev

dev队列下又分为了eng和science队列

root
├── prod
└── dev
    ├── eng
    └── science

下面的配置文件配置了每个队列可占有的资源

<?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>
</xml>

容器调度允许某个队列在资源不够的情况下抢占其他队列的资源,但不能无限制地抢占,maximum-capacity设置了最大抢占资源的百分比。

任务要放在哪个队列,比如Mapreduce任务,可以通过设置mapreduce.job.queuename来指定。

公平调度器

公平调度器的设置和容器调度器的设置差不多,也是通过配置文件来配置队列信息。

通过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>
    <queuePlacementPolicy>
        <rule name="specified" create="false" />
        <rule name="primaryGroup" create="false" />
        <rule name="default" create="dev.eng" />
    </queuePlacementPolicy>
</allocations>
</xml>

父子队列通过<queue>标签的嵌套实现,<weight>指定了队列的资源分配权重,这里设置的两个值只是比例而已,并不是指占据的资源总数,这里的40和60换成2和3也是一样的效果。默认队列和没有指定权重的队列也会占有值为1的权重。

在不同的队列中还可以设置不同的调度方式,有FIFO和Dominant Resource Fairness(drf)策略。

上面的prod队列使用的就是fifo调度策略,但是prod和dev队列之间,eng和science队列之间仍然是公平调度策略。

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

上面这段xml配置指定了应用应该放置到哪个队列,应用会对每条规则逐条进行匹配,specified规则,表示把任务放到指定的队列中,如果没有指明或者指定的队列不存在,则继续下一条规则,create=”false”指的是如果队列不存在是否要创建该队列,默认值是true。

第二条primaryGroup规则指定了把应用放置到以用户的Unix用户组用户名为队名的队列中,简单来说就是放置到名字为当前操作系统用户的用户名队列中,default是最终默认规则,如果什么规则都没匹配上的话,会使用这条规则,这里指定了放入dev.eng队列。

如果去掉<queuePlacementPolicy>标签,则默认的标签内容为

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

换而言之,如果没有指定队列,则会以用户名为队列创建队列,这样会使得多个用户互相争夺资源,比较简单的配置方式如下

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

让所有的任务都在一个队列中,在同一个队列中争夺资源