使用Yarn标签能力实现任务资源隔离

发布于:2024-12-06 ⋅ 阅读:(115) ⋅ 点赞:(0)

我们在工作或自己研究的时候,一般不关注yarn的lable能力,这主要因为业内大部分用的是公有云,即使有私有云或者是独占集群,集群的运维通常也是抛给厂商了,所以这就导致Label的能力被忽视了,并且这个能力默认是关闭的,所以综合一下情况,使用起来就会因为各种用户因素而导致很复杂,懂的都懂。

但其实lable能力提供了一种非常有用的资源标记能力,可以通俗的理解为它主要是用来标记不同nodemanager,来完成一些更细致的任务运行把控,在某些场景下非常有用,比如业内大部分数据服务提供商,都会超卖,这就导致,当集群中有的节点由于任务所需的资源或集群性能瓶颈也或者是其他原因导致机器已经卡的不行了,ssh都过不去,而由于厂商超卖,所以在nodemanager上,当前节点还有资源可以用,后续还有任务再向当前节点提交,所以任务会一直失败,这个时候就可以用label能力屏蔽掉这些节点

想要使用标签功能,需要改一些配置,首先是修改yarn-site.xml文件,开启标签能力

<property>
    <name>yarn.node-labels.enabled</name>
    <value>true</value>
</property>

配置标签提供者:设置标签提供者,这里以配置中心化标签提供者为例
<property>
    <name>yarn.resourcemanager.node-labels.provider</name>
    <value>org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsProvider</value>
</property>

设置标签存储位置:指定标签的存储位置。是一个hdfs路径
<property>
    <name>yarn.node-labels.fs-store.root-dir</name>
    <value>/yarn/node-labels</value>
</property>

随后使用命令为集群添加标签

yarn rmadmin -addToClusterNodeLabels "az1(exclusive=true)"
 
yarn rmadmin -addToClusterNodeLabels "az2(exclusive=true)"
 
# 或者一次性添加两个标签,exclusive表示这个标签对应的资源在空闲时,是否分享给默认标签空间使用
yarn rmadmin -addToClusterNodeLabels "az1(exclusive=true),az2(exclusive=true)"
 
## 删除已添加的标签
yarn rmadmin -removeFromClusterNodeLabels az1,az2
 
## 查看yarn集群已添加的标签
yarn cluster --list-node-labels

这里着重强调一下上面提到的“默认标签空间”,Yarn提供了两种标签和节点资源关系的维护方式,分别是命令方式和配置文件方式,两者能够实现的能力或者说作用不太一样,在使用配置文件方式,对资源进行隔离之后,你在yarn页面上会看到,队列从原来根节点从root做顶级队列展开的单个树结构,变成从标签为根节点开始的多颗树结构,不过它并不会影响任务提交时指定队列的方式,而是按照配置的内容,展示不同标签下队列可使用的资源容量以及情况。也就是说你在提交任务指定队列的时候,使用方式不用调整正常使用即可,而yarn上会以多棵树的方式展示不同队列,使用了不同标签各自所指向运行资源的多少。这里说的默认标签空间是yarn自带的一个默认标签,在正式商用化环境下是不会使用它的,而如果你以命令行的方式使用标签能力,这种方式配置方便,优点是灵活多变,但缺点是只能用来做一些简单或直观的资源隔离,比如当前集群有节点状态不对,为了保证任务的运行,不希望运行在上面,你就可以用命令方式给这些节点打个标签,提交任务的时候通过参数把这些节点过滤掉,不过这就需要让默认标签能访问其他标签的空闲资源,来保证在灵活使用的同时不影响其他任务使用集群资源。反之如果你用的是配置文件的方式,那么队列使用那些标签的资源,能使用多少都在文件中写死了,一般不给默认标签加资源也不会用默认标签,因此不用操心它。同时也意味着两种使用方式并不是100%兼容的,比如一个任务提交时指定运行在那个标签的资源上,但运行的队列没有使用权限,那就菜了,因此使用配置文件方式的集群对外的口径都是统一的不提供提交任务时指定标签资源的能力。总之在具体使用时两种方式不要混用,你就把它看作两个互斥的东西就行。

如果你后面有变动标签和节点关系的需求!!!!切记!!!改完配置文件或者命令调整完后和我之前分享hadoop配置存储和计算节点分离是一样的,一定!!!一定!!!!要先用yarn rmadmin -refreshQueues刷新配置,严禁!!!严禁直接重启yarn!并且命令行和配置文件方式的是不互通的,不要以为可以相互兼容覆盖,会冲突导致出问题。

当你使用配置文件方式的时候,如果遇到了某种极端情况导致你改完标签配置也刷新了配置,但是yarn启动之后无法正常启动action节点,这种情况是因为hdfs上保存的标签数据和yarn启动时识别到的配置文件对不上,解决方法相当简单,去yarn.node-labels.fs-store.root-dir配置的路径下看一眼,维护一下对应的文件,最直接的是把这个文件夹整个删了,也可以改个名,后续方便排查问题和回调分析,这样yarn就可以起来了,对应hdfs路径下的文件会自动重新生成,因此这个东西配置好之后很少变动,因为容易出问题,想要避免这种情况的发生最好是不要随便删除某些配置,如果实在需要先小改一个尝试一下。反正你采用命令行的话,通常不会有这种问题。但是使用命令行只能达到一些很简单的目的,而且相当受限于你使用的版本和底层代码是否支持。个人理解这个label功能不被常用,用户是一部分问题,hadoop本身架构的该功能开发也是不太健全,总会有一些奇奇怪怪的问题,反正从个人工作经验来看,即使用到了label标签功能的商用环境,也只是用它来以配置文件的方式来隔离队列和node资源,其他的相关能力没有遇到过商用的。

1、命令行方式

命令行方式使用相当简单,只需要用如下命令就可以给节点打上标签集合

命令格式:yarn rmadmin -replaceLabelsOnNode <"node1[:port]=label1,label2 node2[:port]=label1,label2"> [-failOnUnknownNodes]

yarn rmadmin -replaceLabelsOnNode "node1=az1"

同理让你要删除一个节点的标签,只需要修改成空即可,例如"node1="

查看yarn界面效果如下:
在这里插入图片描述
在这里插入图片描述
这个时候,你就可以在提交任务的时候,使得任务不允许或只运行在目标标签上,比如你可以用hadoop自带的算子测试一下

#运行在没有az1标签的节点上
hadoop jar /opt/hadoop323/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.3.jar wordcount -D mapreduce.job.nodelabel.expressions=not(az1)  /input /output

#运行在有az1标签的节点上
hadoop jar /opt/hadoop323/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.3.jar wordcount -D mapreduce.job.nodelabel.expressions=az1 /input /output

不过这种指定运行资源的使用方式很受集群的版本和底层代码是否优化的限制,导致很可能不生效,所以如果测试的时候发现不生效,也不需要疑惑,这里写上也只是展示命令行方式关联标签顺带的,我目前没见过有那个厂商,商用提交任务是通过mapreduce.job.nodelabel.expressions调整运行资源的能力,都是使用标签的配置文件方式来实现多租户下的资源隔离

2、配置文件方式

配置文件的方式下,你需要在nodemanager节点上的yarn-site.xml文件中追加如下配置,当然你要是保险起见可以同步所有节点,反正只有nodemanager节点生效

<property>
    <name>yarn.node-labels.configuration-type</name>
    <value>distributed</value>
</property>

<property>
    <name>yarn.nodemanager.node-labels.provider</name>
    <value>config</value>
</property>

这个配置需要每个nodemanager节点各自设置各自的配置
<property>
    <name>yarn.nodemanager.node-labels.provider.configured-node-partition</name>
    <value>az1</value>
</property>

随后重启一下yarn服务,就能在yarn页面上看到节点的标签了,到这一步,其实就相当于命令行方式的配置了
在这里插入图片描述
并且当你查看队列的时候,会发现队列的展示变成了已标签为区块的展示形式,在下图中由于所有节点的标签都是az1,所以可以看到所有资源都在az1下
在这里插入图片描述
配置文件的配置方式还支持限制不同队列,可访问不同标签下,计算资源的比例,比如下面的capacity队列配置,需要时写在capacity队列的配置文件中即可

<property>
    <name>yarn.scheduler.capacity.root.default.accessible-node-labels</name>
    <value>az1,az2</value>
    <description>root.default队列可用的节点标签</description>
</property>
<property>
    <name>yarn.scheduler.capacity.root.default.default-node-label-expression</name>
    <value>az1</value>
    <description>root.default队列应用默认节点标签</description>
</property>

<property>
    <name>yarn.scheduler.capacity.root.default.accessible-node-labels.az1.capacity</name>
    <value>100</value>
    <description>root.default队列对az1标签节点可用的百分比</description>
</property>
<property>
    <name>yarn.scheduler.capacity.root.default.accessible-node-labels.az1.maximum-capacity</name>
    <value>100</value>
    <description>default队列对az1标签节点最大的百分比</description>
</property>
 
<property>
    <name>yarn.scheduler.capacity.root.default.accessible-node-labels.az2.capacity</name>
    <value>100</value>
    <description>default队列对az2标签节点可用的百分比</description>
</property>
<property>
    <name>yarn.scheduler.capacity.root.default.accessible-node-labels.az2.maximum-capacity</name>
    <value>100</value>
    <description>default队列对az2标签节点最大的百分比</description>
</property>
 
<!-- 也可以直接设置 root 队列的 -->
<property>
  <name>yarn.scheduler.capacity.root.accessible-node-labels.az1.capacity</name>
  <value>100</value>
  <description>root队列对az1标签节点最大的可用百分比</description>
</property>
<property>
  <name>yarn.scheduler.capacity.root.accessible-node-labels.az2.capacity</name>
  <value>100</value>
  <description>root队列对az2标签节点最大的可用百分比</description>
</property>

最后在强调一次,你可以尝试去试一试,你使用的版本是否支持提交任务时如下的方式使用标签

MR任务:

-Dmapreduce.job.queueName=default -Dmapreduce.job.node-label-expression=az1
 
# 例子
hadoop jar /data/hadoop-3.1.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.1.jar pi 100 100 -Dmapreduce.job.queueName=default -Dmapreduce.job.node-label-expression=az1

Yarn任务:

-queue default -node_label_expression az1
 
# 例子
hadoop jar /data/hadoop-3.1.1/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-3.1.1.jar -shell_command "sleep 100" -jar /mnt/kmr/hadoop/1/hadoop-3.1.1/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-3.1.1.jar  -num_containers 10 -queue default -node_label_expression az1

Hive任务:

set mapreduce.job.node-label-expression=az1;
set mapreduce.job.queuename=default;

Spark任务:

--conf spark.yarn.am.nodeLabelExpression=az1  
--conf spark.yarn.executor.nodeLabelExpression=az1 
--queue default 
 
# 例子
./bin/spark-submit --class org.apache.spark.examples.SparkPi \
  --master yarn \
  --deploy-mode cluster \
  --driver-memory 2g \
  --executor-memory 2g \
  --conf spark.yarn.am.nodeLabelExpression=az1 \
  --conf spark.yarn.executor.nodeLabelExpression=az1 \
  --queue default \
  jars/spark-examples.jar 10

Flink任务:

#命令中用的是简写,--help可以查看全称
./bin/flink run -m yarn-cluster -yjm 1024 -ytm 1024 -ynl az1 -yqu default

但是如果由于版本等原因,你发现任务控制队列无法生效,也无需过多的困扰,工作中遇到有地方商用再说,而且就算这种提交任务修改运行节点的方式,可以商用,限制也不少,直观的要考虑一下几点

1、用户能使用那些队列,使用的这些队列怎么合理的设置和标签的关系,映射关系是否和实际使用场景兼容,通俗的讲就是任务不止要把控用户使用那些队列,还要维护运行队列,能够访问哪些标签下的资源
2、最头疼的,是一旦对队列设置标签级别的资源把控,你还对用户开放了指定任务执行节点,这会增加用户使用的学习成本,就拿上面的,通过设置标签来屏蔽节点的例子来说,如果用户指定的资源,受限于队列访问标签资源的限制,很容易造成一些不必要的麻烦,就是说你要考虑用户是否能正确的使用标签
3、yarn操作标签不能批量操作,只能一个一个节点的设置,维护起来不方便,如果向用户开放了节点标签的指定那肯定需要来回变动,运维能累死

综上所属,启用节点标签影响单个任务执行情况,这意味着要投入人力去维护标签关系,所以业内一般都是只做到用户多租户,使用各自队列以及限制队列可访问的资源这一级,当然你要确定你要让不同队列的任务,运行在不同的资源上,如果你只是单纯对多租户隔离,其实没有必要用标签,用队列就行了。至于任务提交时需要指定运行节点,来解决节点自身原因造成的拥堵等风险,则处理的很含糊,通常都是重试


网站公告

今日签到

点亮在社区的每一天
去签到