【简介】
hadoop2.7.2开始,yarn在容量调度器的基础上增加了标签调度功能,使用该功能的一个典型场景是:某个任务需要用到gpu资源,而gpu并非在每个节点上都有,通过对节点设置标签,可以使作业任务正确调度到含gpu资源的节点上,确保作业任务正确运行。
本文主要讲解如何正确配置使用标签调度,至于标签调度的一些基本概念可以自行从官网上查看。
【配置使用】
要使用标签调度,首先需要启用标签功能,也就是在rm的配置文件中增加如下配置:
<property>
<name>yarn.node-labels.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.node-labels.fs-store.root-dir</name>
<value>hdfs:///yarn/node-labels</value>
</property>
配置项yarn.node-labels.enabled表示是否启用标签功能。
yarn.node-labels.fs-store.dir表示标签的存储位置,可以是本地文件,也可以是hdfs上的存储路径(文件目录会自动进行创建)
通过修改配置启用标签功能后,接下来就是向集群中添加一些标签,例如使用如下命令添加一个gpu的标签:
yarn rmadmin -addToClusterNodeLabels "gpu(exclusive=true)"
exclusive表示是否独占,具体可以理解为,当该标签分区下的节点有空闲资源时,是否可以共享给default分区的任务使用。
true表示独占,即不共享,资源仅分配给具有该标签的任务使用。
false表示非独占,即可以共享。
添加标签前,rm的界面上,可以看到只有DEFAULT标签(如下图所示)
添加标签后,rm的界面上,就可以看到对应的标签信息了。
另外,从上图可以看出来,gpu,hncscwc两个标签对应的分区中都还没有活跃的NM节点。
完成标签的添加后,接下来就是给指定的节点关联到不同的标签上,也就是将集群的节点按标签划分成不同的节点分区。
yarn rmadmin -replaceLabelsOnNode "192.168.3.51:9100=gpu"
执行上面的命令后,再来看看rm的界面,可以看到gpu的标签,有了一个活跃的节点,而DEFAULT标签中则少了一个活跃节点。
从NM节点列表的界面中,也可以看到该节点有了对应的标签信息。
同时,队列的界面中,也多出了对应的标签信息,所有队列均会出现在所有标签中。
但是,gpu,hncscwc两个标签下,所有队列的容量均为0,即队列还未设置对应标签的使用容量。
在配置文件(capacity-scheduler.xml)中,配置每个队列可以访问的标签,以及每个标签资源的使用容量,例如按如下进行配置:
<!-- spurs队列设置可访问的标签 -->
<property>
<name>yarn.scheduler.capacity.root.spurs.accessible-node-labels</name>
<value>hncscwc,gpu</value>
</property>
<!-- net队列设置可访问的标签 -->
<property>
<name>yarn.scheduler.capacity.root.net.accessible-node-labels</name>
<value>hncscwc,gpu</value>
</property>
<!-- spurs队列可访问gpu标签中的资源百分比 -->
<property>
<name>yarn.scheduler.capacity.root.spurs.accessible-node-labels.gpu.capacity</name>
<value>30</value>
</property>
<!-- net队列可访问gpu标签中的资源百分比 -->
<property>
<name>yarn.scheduler.capacity.root.net.accessible-node-labels.gpu.capacity</name>
<value>70</value>
</property>
<!-- spurs队列可访问hncscwc标签中的资源百分比 -->
<property>
<name>yarn.scheduler.capacity.root.spurs.accessible-node-labels.hncscwc.capacity</name>
<value>30</value>
</property>
<!-- net队列可访问gpu标签中的资源百分比 -->
<property>
<name>yarn.scheduler.capacity.root.net.accessible-node-labels.hncscwc.capacity</name>
<value>70</value>
</property>
配置完成后,通过命令刷新队列使配置生效,在界面中可以看到如下信息:
从上图可以看到,net队列可以访问gpu,hncscwc两个标签的资源,并且在gpu标签中,容量配置为70%。
但是绝对可使用容量(Absolute Configured Capacity)却是0,为什么会这样呢?
回顾上一篇文章中提到的,队列的容量计算时是按系数乘以父队列可以访问的容量,net队列的父队列为root,而root却没有对该标签的容量进行设置,导致出现该问题。
在配置文件中再增加如下配置:
<property>
<name>yarn.scheduler.capacity.root.accessible-node-labels.gpu.capacity</name>
<value>100</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.accessible-node-labels.hncscwc.capacity</name>
<value>60</value>
</property>
刷新后,可以看到net队列的绝对可使用容量已经不再是0了。
这里,有人可能会有这样的疑问?
既然root队列也需要设置不同标签的容量,其子队列才能真正配置到资源,那么root队列是否也和其他队列一样需要配置可访问的标签呢?
刚开始时,我也有这样的疑问,带着问题,查看了相关源码,发现root队列不需要配置可访问的标签,默认就是"*",即可以访问所有的标签,但容量还是要配置。(具体为什么,还没有想清楚,觉得root队列既然默认可以访问所有标签,其容量也应当默认为100才对)
所有配置都完成后,接下来就是提交任务了,由于有的队列可以同时访问多个标签,也就是可以使用多个标签的节点资源,那么具体某个任务应该分配到哪个节点上去,这就是提交任务时需要自行指定标签了。
例如,提交MR任务时,通过如下参数
"-Dmapreduce.job.queueName=net -Dmapreduce.job.node-label-expression=gpu"
指定该任务提交到net队列上,并且指定需要分配到gpu标签对应的节点上。
如果任务提交时没有指定node-label-expression,那么就使用队列的默认标签。
通过如下配置可以指定队列的默认标签
<!-- 队列net设置默认标签为gpu -->
<property>
<name>yarn.scheduler.capacity.root.net.default-node-label-expression</name>
<value>gpu</value>
</property>
另外,标签的配置方式可以通过yarn.node-labels.configuration-type来配置,可选值包括centralized、delegated-centralized、distributed。
centralized为默认值,表示NM节点与标签的映射关系通过rm的管理命令(也就是上介绍的命令方式)、rest接口、rpc请求来进行统一控制。
delegated-centralized表示由rm内部决定,通常是自行编写类,继承RMNodeLabelsMappingProvider,来实现节点与标签的关联关系。
distributed表示nm自行配置并上报标签信息。
有兴趣的小伙伴,可以自行研究下如何配置。