YARN资源管理的最佳实践
网友 CSDN

在这篇博文中,我将讨论YARN资源管理的最佳实践。MRV2(YARN)的基本思想是将资源管理和作业调度/监控两大功能分为独立的守护进程。这个想法是拥有一个全局ResourceManager(RM)和每个应用程序的ApplicationMaster(AM)。应用程序是单个作业或作业的DAG。

ResourceManager(RM)和每个从属节点(NM)构成数据计算框架。 ResourceManager拥有在系统中的所有应用程序之间仲裁资源的最终权力。NodeManager是每个机器的架构代理,负责监视容器的资源使用情况(cpu,内存,磁盘,网络)并将其报告给ResourceManager / Scheduler。

在进行接下来的讨论之前,先熟悉一下YARN.

image.png

每个应用程序ApplicationMaster实际上是一个框架特定的库,任务是从ResourceManager协商资源,并与NodeManager一起执行和监视任务。

ResourceManager有两个主要组件:Scheduler和ApplicationsManager。

Scheduler 负责根据容量,队列等的常见限制,向各种运行的应用程序分配资源。Scheduler 是纯调度器,它不执行监视或跟踪应用程序的状态。此外,由于应用程序故障或硬件故障,它不能保证重新启动失败的任务。Scheduler 根据应用程序的资源需求执行调度功能;它的功能实现基于包含诸如内存,cpu,磁盘,网络等元素的资源容器Container的抽象概念。

Scheduler 具有可插拔策略,负责在各种队列,应用程序等之间划分集群资源。目前的Scheduler 如CapacityScheduler和FairScheduler是插件的一些示例。

ApplicationsManager负责接受作业提交,协商第一个容器来执行应用的特定ApplicationMaster,并提供重新启动ApplicationMaster容器失败的服务。每个应用程序ApplicationMaster负责从Scheduler协商适当的资源容器containers,跟踪其状态并监视进度。

MapReduce 在hadoop-2.x中保持了和hadoop-1.x的兼容性,这意味着无需更改代码.只需要重新编译之后,程序能够正常运行。

YARN通过 ReservationSystem 来支持资源预留(resource reservation)的概念。该功能支持预留资源以确保重要的作业能够可预测的执行。

本博客文章涵盖了有关YARN资源管理的以下主题,并为每个主题提供了最佳实践:

1:Warden如何计算和分配资源给YARN?

2:YARN中的最小和最大分配单位

3:虚拟/物理内存检查器

4:Mapper,Reducer和AM的资源请求

5:瓶颈资源


1.1:Warden如何计算和分配资源给YARN?

在一个MapR Hadoop集群,Warden设置操作系统,MapR-FS,MapR Hadoop服务和MapReduce v1和YARN应用程序的默认资源分配。详细信息在MapR文档中描述:Resource Allocation for Jobs and Applications

YARN可以管理3个系统资源 - 内存,CPU和磁盘。监视器完成计算后,将设置环境变量YARN_NODEMANAGER_OPTS以启动NM。

例如,如果你执行" vi /proc//environ",能够发现:

 

YARN_NODEMANAGER_OPTS= -Dnodemanager.resource.memory-mb=10817

-Dnodemanager.resource.cpu-vcores=4

-Dnodemanager.resource.io-spindles=2.0

 

可以通过在NM节点上的yarn-site.xml中设置以下三个配置并重新启动NM来覆盖它们。

  • yarn.nodemanager.resource.memory-mb

  • yarn.nodemanager.resource.cpu-vcores

  • yarn.nodemanager.resource.io-spindles

要查看每个节点的可用资源,你可以访问RM UI(http://:8088 / cluster / nodes),并从每个节点中找出"Mem Avail","Vcores Avail"和"Disk Avail"。

image.png

 

    如果内存过量分配给YARN,可能发生swap,并且 kernel OOM killer有可能会触发kill container进程. 以下错误是OS OOM的标志,可能内存已超量分配给YARN。

 

os::commit_memory(0x0000000000000000, xxxxxxxxx, 0) failed;

error='Cannot allocate memory' (errno=12)

    

如果我们看到,只需要仔细检查一下,warden是否考虑到该节点上的所有内存消耗服务,并且如果需要,减少由warden分配的内存。

 

image.png

1.2. YARN中的最小和最大分配单位    

两个资源 - 内存和CPU,如Hadoop 2.5.1,在YARN中具有最小和最大的分配单位,由以下配置在yarn-site.xml中设置:

    基本上,这意味着RM只能以"yarn.scheduler.minimum-allocation-mb"为增量分配容器,而不能超过"yarn.scheduler.maximum-allocation-mb";

并且它只能以"yarn.scheduler.minimum-allocation-vcores"为增量分配CPU容量,而不能超过"yarn.scheduler.maximum-allocation-vcores"。

如果需要更改,请在RM节点上的yarn-site.xml中设置上述配置,然后重新启动RM。

例如,如果一个作业要求每个map container 1025 MB的内存(set mapreduce.map.memory.mb = 1025),则RM将给它一个2048 MB(2 * yarn.scheduler.minimum-allocation-mb)container。

如果你有一个巨大的MR作业要求一个9999 MB的map container,则该作业将在AM日志中的以下错误消息中被杀死:

 


MAP capability required is more than the supported max container capability in the cluster.


Killing the Job. mapResourceRequest: 9999 maxContainerCapability:8192

 

    如果一个Spark on YARN工作要求一个巨大的Container,大小大于"yarn.scheduler.maximum-allocation-mb",下面的错误会显示出来:


Exception in thread "main" java.lang.IllegalArgumentException:


Required executor memory (99999+6886 MB) is above the max threshold (8192 MB) of this cluster!

 

在上述两种情况下,你可以在yarn-site.xml中增加"yarn.scheduler.maximum-allocation-mb"并重新启动RM。

    所以在这一步中,你需要熟悉每个mapper和作业的reducer的资源需求的下限和上限,并根据此设置最小和最大分配单元。

image.png

1.3:虚拟/物理内存检查器

    NodeManager可以监视容器的内存使用情况(虚拟和物理)。如果虚拟内存超过"yarn.nodemanager.vmem-pmem-ratio"乘以"mapreduce.reduce.memory.mb"或"mapreduce.map.memory.mb",若"yarn.nodemanager.vmem-check-enabled"设置为true,那么这个container会被kill.

    如果其物理内存超过"mapreduce.reduce.memory.mb"或"mapreduce.map.memory.mb",则如果"yarn.nodemanager.pmem-check-enabled"为真,则容器将被终止。

    以下参数可以在每个NM节点的yarn-site.xml中进行设置,以覆盖默认行为。

这是虚拟内存检查程序杀死的容器的示例错误:


Current usage: 347.3 MB of 1 GB physical memory used;


<font color="red">2.2 GB of 2.1 GB virtual memory used</font>. Killing container.

这是物理内存检查器的示例错误:


Current usage: <font color="red">2.1gb of 2.0gb physical memory used</font>;


1.1gb of 3.15gb virtual memory used. Killing container.

与MapR 4.1.0的Hadoop 2.5.1一样,默认情况下启用物理内存检查,虚拟内存检查器被禁用。

由于在Centos / RHEL 6上,由于操作系统的行为,存在虚拟内存的大量分配,你应该禁用虚拟内存检查器或将yarn.nodemanager.vmem-pmem-ratio增加到一个相对较大的值。

如果发生上述错误,MapReduce作业也有可能泄漏内存,或者每个容器的内存都不够。尝试检查应用程序逻辑,并调整容器内存请求—"mapreduce.reduce.memory.mb" or "mapreduce.map.memory.mb".


1.4: Mapper,Reducer和AM的资源请求

    MapReduce v2作业有3种不同的容器类型 - Mapper,Reducer和AM。 Mapper和Reducer可以要求资源 - 内存,CPU和磁盘,而AM只能要求内存和CPU。以下是三种容器类型的资源请求的配置摘要. 默认值来自MapR 4.1的Hadoop 2.5.1,它们可以在客户端节点的mapred-site.xml中被覆盖,也可以在MapReduce java代码,Pig和Hive Cli等应用程序中设置。


  1. image.png


 

每个容器实际上都是一个JVM进程,并且java-opts的"-Xmx"上面应该适合分配的内存大小。一个最佳做法是设置为0.8 *(容器内存分配)。例如,如果请求的映射器容器具有mapreduce.map.memory.mb = 4096,我们可以设置mapreduce.map.java.opts = -Xmx3277m。

有许多因素会影响每个容器的memory需求。这些因素包括Mappers / Reducers的数量,文件类型(plain text file , parquet, ORC),数据压缩算法,操作类型(sort, group-by, aggregation, join),数据偏移等。你应该熟悉MapReduce工作的性质,并找出Mapper,Reducer和AM的最低要求。任何类型的容器都可能用完内存,并被物理/虚拟内存检查器杀死,如果它不符合最低内存要求。如果是这样,你需要检查AM日志和发生故障的容器日志以找出原因。

例如,如果MapReduce作业对parquet文件进行排序,Mapper需要将整个Parquet行组缓存在内存中。我已经做了测试 ,以证明parquet文件的行组大小越大,需要更大的Mapper内存。在这种情况下,请确保Mapper内存足够大,无需触发OOM。

另一个例子是AM内存不足。通常,AM的1G Java堆大小对于许多作业来说已经足够了。但是,如果工作要写大量的parquet文件,在作业的提交阶段,AM将调用ParquetOutputCommitter.commitJob()。它将首先读取所有输出parquet文件的页脚,并在输出目录中写入名为"_metadata"的元数据文件。

此步可能导致AM 的OOM :


Caused by: <font color="red">java.lang.OutOfMemoryError</font>: GC overhead limit exceeded


at java.lang.StringCoding$StringEncoder.encode(StringCoding.java:300)


at java.lang.StringCoding.encode(StringCoding.java:344)


at java.lang.String.getBytes(String.java:916)


at parquet.org.apache.thrift.protocol.TCompactProtocol.writeString(TCompactProtocol.java:298)


at parquet.format.ColumnChunk.write(ColumnChunk.java:512)


at parquet.format.RowGroup.write(RowGroup.java:521)


at parquet.format.FileMetaData.write(FileMetaData.java:923)


at parquet.format.Util.write(Util.java:56)


at parquet.format.Util.writeFileMetaData(Util.java:30)


at parquet.hadoop.ParquetFileWriter.serializeFooter(ParquetFileWriter.java:322)


at parquet.hadoop.<font color="red">ParquetFileWriter.writeMetadataFile</font>(ParquetFileWriter.java:342)


at parquet.hadoop.<font color="red">ParquetOutputCommitter.commitJob</font>(ParquetOutputCommitter.java:51)


... 10 more

    解决方案是增加AM的内存需求,并通过"set parquet.enable.summary-metadata false"禁用该parquet功能。

    除了找出每个容器的最低内存需求外,有时我们需要平衡工作性能和资源能力。例如,进行排序的作业可能需要相对较大的"mapreduce.task.io.sort.mb",以避免或减少溢出文件的数量。如果整个系统具有足够的内存容量,我们可以增加"mapreduce.task.io.sort.mb"和容器内存,以获得更好的工作性能。

在此步骤中,我们需要确保每种类型的容器满足适当的资源要求。如果OOM发生,请始终先检查AM日志,找出哪个容器以及每个stack trace的原因。


1.5 瓶颈资源

    由于有三种资源类型,不同工作的不同容器可能会要求不同的资源数量。这可能导致其中一个资源成为瓶颈。假设我们有一个容量集群(1000G RAM,16个核心,16个磁盘),每个Mapper容器需要(10G RAM,1个核心,0.5个磁盘):最多可以并行运行16个Mappers,因为CPU核心成为这个瓶颈。

    因此,任何人都不会使用(840G RAM,8个磁盘)资源。如果您遇到这种情况,只需检查RM UI(http://:8088 / cluster / nodes),找出哪个资源是瓶颈。您可以将剩余资源分配给可以通过此类资源提高性能的作业。例如,您可以将更多的内存分配给排序job,防止用溢出到磁盘。


1.6 总结

(1) 熟悉mapper和reducer的资源需求的下限和上限。

(2) 注意虚拟和物理内存检查器。

(3) 将每个容器的java-opts的-Xmx设置为0.8 *(容器内存分配)。

(4) 确保每种类型的容器满足适当的资源需求。

(5) 充分利用瓶颈资源。


CIO之家 www.ciozj.com 公众号:imciow
关联的文档
也许您喜欢