技术分享 | YARN在混合异构集群下的使用

2022-04-18

分享到

前言


Hadoop-Yarn作为一款开源的大数据分布式资源管理与调度框架,经过数十年的发展,目前已经成为了业界内使用最广的资源调度框架之一,其主要功能是协同大数据计算框架,来完成分布式大数据计算过程中的资源管理与调度。

常见的资源管理需求例如:划分资源队列、资源的共享、资源的抢占、资源的动态扩展、资源队列的权限设置等,这些需求在实际生产中的应用十分广泛,Yarn可以很好的覆盖这些需求并提供有力的支撑。

除此之外,Yarn还可以应对一些复杂场景下的资源管理需求,接下来通过业务场景带入来逐步介绍我们的解决方案。


业务场景分析

首先介绍我们在实际生产中的业务场景,描述下实际场景中的业务需求。


· 业务场景


在我们的业务场景下,有多种分布式作业类型,具体包括:


· MapReduce作业:我们使用MapReduce进行CPU运算,但MapReduce在2.10.1版本中也开始正式支持GPU运算[1]


· Spark作业:一般是使用CPU进行运算,同时还可以通过参数来控制其是否调用GPU进行运算;


· MPI作业[2]同Spark,可能需要使用GPU来加速运算;


· AI作业:一般是使用GPU进行运算,也可以使用CPU进行运算[3]


[1]https://issues.apache.org/jira/browse/YARN-9444
[2]https://github.com/alibaba/mpich2-yarn

[3]https://github.com/tensorflow/ecosystem/blob/master/spark/spark-tensorflow-distributor/spark_tensorflow_distributor/mirrored_strategy_runner.py





这些不同类型的作业对资源需求不同,因此需要我们的集群中的部分节点包含GPU,用于运行需要GPU加速的作业,另一部分为CPU节点,用于运行纯CPU运算的作业。

由于在我们当前的场景下,大部分是CPU作业,所以当GPU节点没有作业运行时,还需要可以将其节点上的CPU资源共享出来,供CPU作业使用,这样可以有效的防止资源浪费。


· 需求分析


为了能够很好的支持当前业务场景下多种不同类型的分布式作业运行的需求,需要Yarn具备以下能力:


· 需要支持GPU资源的管理调度


· 支持CPU、GPU混合异构集群的管理能力


解决方案

通过对Yarn的深入了解后发现Yarn可以很好的解决这些需求。


1、支持GPU的管理调度


Yarn在2.10版本后开始支持GPU的管理功能,目前仅支持capacity调度方式来管理GPU,通过配置resource-types.xml、yarn-site.xml、capacity-scheduler.xml后实现了Yarn对GPU的管理,可与CPU、内存资源一同纳入队列的资源分配池中,作为队列的可用资源供作业申请使用,基本配置如下:


· resource-types.xml文件:


<configuration>
  <property>
     <name>yarn.resource-types</name>
     <value>yarn.io/gpu</value>
  </property>
</configuration>

· capacity-scheduler.xml:


yarn.scheduler.capacity.resource-calculator= org.apache.hadoop.yarn.util.resource.DominantResourceCalculator

其它更多配置详见:https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/UsingGpus.html

在实际应用中,遇到了一个官网上没有提及的问题,即$HADOOP_HOME/etc/hadoop/container-executor.cfg文件的所有父目录的owner都需要为root,有两种方式解决,一是将该文件的所有父目录的owner手动都修改为root;另一种方式就是在yarn-site.xml中配置yarn.nodemanager.linux-container-executor.path的值到自定义路径下,然后将该文件单独复制到该自定义路径下,然后仅修改该路径的权限为root即可。


2、支持CPU、GPU混合异构集群的管理能力

Yarn在Capacity调度方式下使用GPU时,如果队列采用百分比配置会造成资源的浪费:假设共集群中共10块GPU,除非GPU队列配置100%,否则都会造成GPU的浪费。且Yarn目前不支持对GPU采用绝对值的配置(详见:https://issues.apache.org/jira/browse/YARN-9161),因此考虑采用混合配置,即CPU配置绝对值,GPU配置100%。


这种配置方式虽然可以同时运行CPU和GPU作业,但是会出现以下问题:

1) CPU作业抢占资源导致GPU作业无法运行的情况,出现GPU浪费;

2) 这种配置方式导致实际资源量超出100%了,Yarn无法正常管理,会出现CPU队列抢占的资源无法正常退还等问题。

因此引入了Yarn的节点标签功能。


· 节点标签


节点标签就是为每个NodeManager节点打上标签,一组相同标签的节点为一个分区,然后将资源队列绑定到分区上,进而通过控制用户提交作业的队列来实现GPU作业仅提交到GPU节点上。

节点标签功能,可以将整个集群分成CPU分区(默认为DEFAULT分区)和GPU分区,CPU分区中全部是CPU节点,GPU分区中全部是GPU节点。

节点标签有两种策略,分别是:


· Exclusive: 分区内的资源完全独立,不会分配给其他的分区;


· Non-exclusive:  分区内的资源可以向CPU分区共享。


通过节点标签进行分区后,向CPU分区提交CPU作业,同时配置GPU分区的Exclusive策略,则可以完全避免CPU作业抢占GPU分区的资源。

同时在GPU分区内配置资源比例为100,也可以避免GPU资源的浪费。

如果希望GPU节点空闲时可以将CPU资源共享出去的话, 则可以配置GPU分区策略为Non-exclusive来实现共享。

使用节点标签时有一点需要特别注意,在设置root.<queue-name>.accessible-node-labels=<分区名>的时候要首先设置root. accessible-node-labels=<分区名>,即设置子队列可达某个分区之前,必须首先设置root队列可达该分区,且root队列可用该分区资源的100%。

通过节点标签功能,实现了对CPU和GPU资源的混合管理,保证两种不同类型的作业可以同时运行,且不会互相影响。


总结

本文结合实际业务场景,介绍了Yarn的部分高级功能,除本文所描述的功能外,Yarn还有更多其他的高级功能,例如Yarn还支持在Docker容器中运行作业、支持对FGPA设备的管理等,尽管Yarn作为分布式资源调度框架已经十分出色,但是在docker容器的调度方面确不如k8s,因此我们在生产中可以根据实际业务需求来进行技术选型。