Yarn Lable 实践

Posted on Sun, Nov 28, 2021 Hadoop Yarn

Yarn Label 可以基于节点标签的信息,对任务的分布进行细粒度控制。该特性从 Hadoop 2.6 版本开始引入,到了 Hadoop 2.8 开始才较为成熟,可以根据节点的一些角色定位、处理能力(结合具体业务场景)等按需对节点划分为几个不同的区域(分组),并可以让作业在指定分区下的节点上运行。

当前 Yarn Label 只能基于 Capacity 调度方式进行工作,暂不支持其他调度方式。

Yarn Label 需要结合节点、用户队列使用,三者结构如下:

一个 Label 下可以有多个 Node,一个 Lable 可以被多个 Queue 共享,一个 Queue 可以有多个 Lable。

1. 开启 Yarn Lables 相关功能

环境信息如下:

首先开启 Yarn 服务下的 Node Labels 功能(等同于修改 yarn-site.xmlyarn.node-labels.enabled 为 true):

在 HDFS 上创建一个存储 Node Lables 信息的路径:

sudo su hdfs
hadoop fs -mkdir -p /yarn/node-labels
hadoop fs -chown -R yarn:yarn /yarn
hadoop fs -chmod -R 700 /yarn

创建 yarn 用户目录:

hadoop fs -mkdir -p /user/yarn
hadoop fs -chown -R yarn:yarn /user/yarn
hadoop fs -chmod -R 700 /user/yarn

修改 Yarn 服务的 YARN Node Labels FS Store Root directory 存储路径为前面 HDFS 创建好的路径(相当于修改 yarn-siteyarn.node-labels.fs-store.root-dir 属性):

重启 Yarn 服务。

2. 添加 Node Labels

Node Lables 会根据我们指定的 label,将集群的节点划分为一个个 partition,一个节点只可以有一个 lable。如果不分配 lable,则节点默认属于 Default partition(即 partition="")。

这里我们添加 kunpeng 以及 dell 两种 label:

sudo -u yarn yarn rmadmin -addToClusterNodeLabels "kunpeng(exclusive=true),dell(exclusive=true)"

exclusive 表示 partition 是否独占,默认为 true。两种配置的含义分别如下:

关于独占与非独占的区别,更具体的信息可以参考 HDP 的文档:Chapter 5. Node Labels

绝大部分场景下,最好设置为独占,让分布式作业只跑在一种架构下,避免低配的机器与高配机器产生 “木桶原理” 的现象。

如果需要删除 label,则需要确保 label 没有分配到队列才能删除:

sudo -u yarn yarn rmadmin -removeFromClusterNodeLabels "<label>[,<label>,...]"

如果需要查看创建的 label,执行下列命令:

sudo -u yarn yarn cluster --list-node-labels

3. 节点分配 Label

节点分配 label 的语法如下:

sudo -u yarn yarn rmadmin -replaceLabelsOnNode "node1[:port]=label1 node2=label2" [-failOnUnknownNodes]

如果不指定 [:prot] ,就会分配给该节点上的全部 NM,从这里也可以看出,Node Labels 的作用粒度其实是在 NM 上,而非节点上,一个节点可以有多个 NM。

如果指定了 -failOnUnknownNodes,那么当命令中有未知节点时,命令会失败。

如果想要查看节点分配的 label,需要先获取节点的 ID,例如(下列信息来自 HDP 文档):

 [root@node-1 /]# sudo -u yarn yarn node -list
 14/11/21 12:14:06 INFO impl.TimelineClientImpl: Timeline service address: http://node-1.example.com:8188/ws/v1/timeline/
 14/11/21 12:14:07 INFO client.RMProxy: Connecting to ResourceManager at node-1.example.com/240.0.0.10:8050
 Total Nodes:3
  Node-Id Node-State Node-Http-Address Number-of-Running-Containers
 node-3.example.com:45454 RUNNING node-3.example.com:50060 0
 node-1.example.com:45454 RUNNING node-1.example.com:50060 0
 node-2.example.com:45454 RUNNING node-2.example.com:50060 0

然后根据节点 ID 获取节点的具体信息:

 [root@node-1 /]# yarn node -status node-1.example.com:45454
 14/11/21 06:32:35 INFO impl.TimelineClientImpl: Timeline service address: http://node-1.example.com:8188/ws/v1/timeline/
 14/11/21 06:32:35 INFO client.RMProxy: Connecting to ResourceManager at node-1.example.com/240.0.0.10:8050
 Node Report :
  Node-Id : node-1.example.com:45454
  Rack : /default-rack
  Node-State : RUNNING
  Node-Http-Address : node-1.example.com:50060
  Last-Health-Update : Fri 21/Nov/14 06:32:09:473PST
  Health-Report :
  Containers : 0
  Memory-Used : 0MB
  Memory-Capacity : 1408MB
  CPU-Used : 0 vcores
  CPU-Capacity : 8 vcores
  Node-Labels : x

3. 队列绑定 Label

NM 分配 node 有 CentralizedDistributedDelegated-Centralized 这几种方式,Ambari 默认为第一种方式。

Centralized:节点与 label 的映射可以通过 RM 暴露的 CLI, REST 或者 RPC 进行配置。

在 Ambari 的队列配置界面,配置 root 父队列占用 kunpeng、dell 的全部资源,同时设置任务不指定 label 时默认 label 为 kunpeng :

配置 haohan、default 队列各占 kunpeng、dell 一半资源:

子队列无需配置默认 label,默认会继承父队列的规则。Ambari 会按照 Yarn 的规则,自动生成相应的配置。

最后点击保存并刷新队列:

这里有一点需要注意,同个 label 在不同队列中也是需要指定百分比的,不同队列相同 label 最终的比例之和需要等于 100%,此时队列之间的资源比例,仅作用于未指定 label 的节点上

配置完毕之后,可以通过以下几种方式指定 label:

API 方式

Hadoop 运行 jar 包方式

hadoop jar xxx.jar -Dmapreduce.job.node-label-expression="label1" -Dmapreduce.job.queuename="queue1"

Spark 可以通在 spark-submit 添加参数来指定 label

 --conf spark.yarn.am.nodeLabelExpression=label1 \
 --conf spark.yarn.executor.nodeLabelExpression=label1

4. 测试

执行 TPC-DS 项目来生成测试数据,在 hadoop 提交任务处指定 label,可以看到提交的 MR 作业都落在指定了 kunpeng 标签的单个节点上:

参考文档