MapReduce On Yarn的配置详解和日常维护

时间:2024-09-27 15:33:14

        MapReduce On Yarn的配置详解和日常维护

                                     作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.MapReduce运维概述

    MapReduce on YARN的运维主要是针对CPU和内存资源的运维。 

二.MapReduce配置详解

1>.以下参数讲解以社区版2.6.0的参数名和默认值为准(配置文件为:hdfs-default.xml / hdfs-site.xml )

  MapReduce 参考链接:http://hadoop.apache.org/docs/r2.6.0/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml

  YARN 参考链接:http://hadoop.apache.org/docs/r2.6.0/hadoop-yarn/hadoop-yarn-common/yarn-default.xml

2>.mapreduce.task.io.sort.factor 

  默认为10。当一个map task执行完后,本地磁盘上(由 mapreduce.cluster.local.dir指定)有若干个spill(溢出)文件,map task最后需要执行merge sort,把这些spill文件合并成一个文件,合并时可以同时打开多少个spill文件由该参数决定。如果有大量数据溢出到磁盘,且merge sort阶段的I/O很高,就应该尝试增加该值,通常社区版的默认值10过小,CDH版的默认值64对中等规模集群合适。各Job也可以单独指定。   

3>.mapreduce.task.io.sort.mb 

  默认值100。用于设置map task的merge sort可用的缓冲区大小,在map输 出较大且map端I/O很高时,就应该尝试增加该值,通常社区版的默认值 100过小,CDH版的默认值256对中等规模集群合适。各Job也可以单独指定。 

4>.mapreduce.cluster.local.dir 

  默认为${hadoop.tmp.dir}/mapred/local。MapReduce保存中间数据文件 的本地磁盘路径,可以通过逗号分隔指定多个路径。可按需修改。

5>.mapreduce.job.maps / mapreduce.job.reduces 

    默认为2/。每个Job默认的map/reduce task个数,各Job也可以单独指定, 因此集群层面的默认值不一定需要修改。 

6>.mapreduce.task.timeout 

  默认为6000000,即10分钟。指定一个task由于没有读取任何数据、写出任何数据或更新状态达到多长时间后会被终止。设为0表示禁用该特性。 

7>.mapreduce.map.memory.mb / mapreduce.reduce.memory.mb

  默认均为1024,调度器为每个map/reduce task申请的内存数。各Job也可 以单独指定。 

8>.mapreduce.map.cpu.vcores / mapreduce.reduce.cpu.vcores 

  默认均为1,调度器为每个map/reduce task申请的CPU虚拟核数。各Job也 可以单独指定。 

9>.mapreduce.map.speculative / mapreduce.reduce.speculative

  默认均为true,是否开启map/reduce task的推测执行特性,我们在核心 课中介绍过推测执行可以解决部分task运行得特别慢的问题,但会消耗额 外的资源,并且非幂等的MR任务不能启用推测执行,否则会影响结果的正 确性。因此,像CDH这样的发行版将默认值设为false。 

10>.mapreduce.job.ubertask.enable 

  默认为false。MapReduce中有一类足够小的作业称为“ubertask”,如果 开启该选项,会在单一JVM内运行该作业的所有task,使得小任务执行时 不需要在节点间交换数据。是否开启区别不大。

11>.mapreduce.output.fileoutputformat.compress 

  默认为false。指定MR的最终输出结果是否压缩。各Job也可以单独指定。 

12>.mapreduce.output.fileoutputformat.compress.type 

  默认为RECORD。可以为NONE,RECORD,BLOCK,如果输出结果要压缩,以什么单位进行压缩。CDH集群该值默认为BLOCK,即以块为单位进行压缩。 

13>.mapreduce.job.queuename 

    默认为default。MR作业提交的默认队列名。各Job也可以单独指定。 

14>.yarn.app.mapreduce.am.staging-dir 

  默认为/tmp/hadoop-yarn/staging。MR作业在提交时所使用的临时目录, 是一个本地路径。 

15>.mapreduce.am.max-attempts 

  默认为2。AM在失败前可以尝试多少次,如果为2,代表可以在1次失败后 有1次重试。该值必须小于YARN的RM的max-attempts值,否则会被覆盖。 各Job也可以单独指定。 

16>.yarn.app.mapreduce.am.resource.mb 

  默认为1536。MR运行于YARN上时,为AM分配多少内存。默认值通常来说过 小,建议设置为2048或4096等较大的值。

17>.yarn.app.mapreduce.am.resource.cpu-vcores

  默认为1。MR运行于YARN上时,为AM分配多少个虚拟核。因为AM并不太消 耗CPU,默认值通常够用。 

18>.mapreduce.app-submission.cross-platform 

  默认为false。我们在核心课中曾经修改过该参数,尤其是使用测试环境 调试时,如果需要用windows、MAC操作系统上的IDE向集群提交作业,应 该将该值设为true。 

19>. yarn.acl.enable 

  默认为false,是否开启YARN的ACL权限控制,在生产集群强烈建议开启, 避免未授信用户随意启动或杀死作业。 

20>.yarn.admin.acl 

    作为YARN的管理员的账号列表,默认为*,即所有账号都视为管理员。 YARN的管理员可以提交作业、杀死作业、移动作业队列等,而普通用户是 只读的。在生产集群建议将该列表限制为yarn,hdfs,dr.who等几个。 

21>.yarn.resourcemanager.am.max-attempts 

    默认为2。见mapreduce.am.max-attempts

22>.yarn.resourcemanager.scheduler.class 

  默认为"org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler",即使用基于容量的调度器。

23>.yarn.scheduler.minimum-allocation-mb / yarn.scheduler.maximumallocation-mb 

  分别为1024/,指定RM可以为每个container分配的最小/最大内存数,低于或高于该限制的内存申请,会按最小或最大内存数来进行分配。默认值适合一般集群使用,如果集群需要运行超耗内存的任务,观察到container有OOM情况,可以调大最大值。 

24>.yarn.scheduler.minimum-allocation-vcores / yarn.scheduler.maximum-allocation-vcores

  分别为1/,指定RM可以为每个container分配的最小/最大虚拟核数,低 于或高于该限制的核申请,会按最小或最大核数来进行分配。默认值适合 一般集群使用。 

25>.yarn.resourcemanager.ha.enabled

  默认为false。指定是否启用YARN的HA,如果启用,还涉及到 yarn.resourcemanager.ha.rm-ids来配置HA组中的多个RM,以及 yarn.resourcemanager.ha.automatic-failover.enabled等参数来配置自动故障转移。 

26>.yarn.resourcemanager.max-completed-applications 

  默认为10000。指定RM最多保存多少个完成作业的信息,超过该门限之前 的作业,将无法通过RM的管理页面(或yarn命令)查询到信息。对比较繁 忙的生产集群,该值过小,会给故障排查带来困难,建议按需调整。 

27>.yarn.log-aggregation-enable 

  默认为false。是否开启YARN的日志聚合功能,如果开启,各container的 日志会被收集到一起并统一存放(如存到HDFS),之后可以通过Timeline Server进行方便的查询。对生产集群建议开启。 

28>.yarn.nodemanager.resource.memory-mb 

    默认为8192。每个节点可分配多少物理内存给YARN使用,考虑到节点上还 可能有其他进程需要申请内存,该值设置为物理内存总数/.3比较合适, 例如128G内存的节点可以分配100G

29>.yarn.nodemanager.pmem-check-enabled / yarn.nodemanager.vmemcheck-enabled / yarn.nodemanager.vmem-pmem-ratio 

  这三个参数控制着YARN对container的内存监控。前两个值默认均为true, 指定是否开启对物理内存/虚拟内存的监控,一旦使用的物理内存或虚拟 内存超过预设值,即会抛出OOM错误,使container被杀死。第三个参数默 认为2.,控制虚拟内存为物理内存的多少倍,如某container申请的最大 物理内存为2G,则虚拟内存可以到4.2G。这三个参数通常都不需要动,但 是需要理解其含义以进行排错。   

30>.yarn.nodemanager.resource.cpu-vcores

  默认为8。每个节点可分配多少虚拟核给YARN使用,通常设为该节点定义 的总虚拟核数即可。 

31>.yarn.timeline-service.enabled 

  默认为false。是否启用Timeline Server,生产环境建议打开。 
  此外,配置了某种scheduler后,还需要修改相应的capacityscheduler.xml或fair-scheduler.xml文件。

三.故障管理

  MRv2日常维护的一个重要部分是处理MapReduce作业(包括Hive作业) 的各种错误。错误类型繁多,这里列举最为常见的几种:

1>.AccessControlException: Permission denied 

  MR作业运行时需要向HDFS写入临时数据,运行完后也可能需要将最终结果 写入HDFS。如果运行MR作业的账号对指定目录没有写入权限,即抛出 AccessControlException异常。这种情况在开启了Kerberos认证的集群上 更容易出现。解决方案也很简单,给目录足够的权限,或改变运行账号。 

2>.ClassNotFoundException

  该异常通常是因为没有找到运行MR作业所需的jar包,使得代码中引用的 某些类找不到。该问题在调试时尤其常见,在代码上线后应该不会出现, 除非有人破坏了CLASSPATH。解决方法是,将所需jar包加入CLASSPATH, 或将所需jar包直接打在MR作业的jar包中。 

3>.Task的JVM堆内存溢出 

常见的征兆有:
java.lang.OutOfMemoryError: GC overhead limit exceeded; running beyond physical memory limits.Current usage: XX GB of XX GB physical memory used等。 治标的方法是:
  改大task的堆内存分配,即调大mapreduce.map.java.opts / mapreduce.reduce.java.opts两个参数的Xmx值。但一味调大Xmx很多时候 不能根本上解决问题,如果将Xmx倍增2、3次后仍然会OOM,就要从代码层面寻找原因,排除过度使用堆内存的隐患。

4>.Task的栈内存溢出,java.lang.*Error 

  比较罕见,通常是因为递归调用、调用链太长导致的。该问题需要从代码层面排除。 

5>.ApplicationMaster堆内存溢出

在MRv2中比较罕见,通常是因为输入数据太大,或指定的map数太多,使得AM的内存不足以管理如此多的map。

解决方法:
将“yarn.app.mapreduce.am.resource.mb”调大。另外该问题在Spark on YARN 时出现的可能性大,此时Spark Driver相当于AM,如果执行Spark Streaming并有很多个微批延时,容易出现Driver内存溢出的情况

6>.非堆内存溢出,java.lang.OutOfMemoryError:Direct buffer memory 

  这种情况在MRv2中也较罕见(Spark on YARN时较多),原因是在代码中 使用了NIO等会使用非堆内存的特性。解决该问题还是要从代码层面优化。 

7>. ClassCastException: org.apache.hadoop.io.XXX cannot be cast to org.apache.hadoop.io.XXX 

  典型的类型转换错误,通常出现在Java实现的MR程序中,mapper和 reducer的输入输出类型是有一定限制的,比如mapper的第一个参数类型 必须是LongWritable或NullWritable,mapper的输出类型必须和reducer 的输入类型一致,否则就会出现此类问题。解决办法是调整代码。 

8>.java.io.IOException 

  出现该异常的场景很多,如读写HDFS错误、RPC请求超时、网络配置错误 等。需要根据更细节的信息(如异常堆栈)进一步排查,通常都是比较明 显的错误。

9>.其他错误

  通过日志排查。MRv2作业问题通常都只需要分析container日志,该日志位于Hadoop安装目录的userlogs目录下的application_xxx目录下,有多个container的话就有多个container_xxx_0000xx目录,最内层有stdout, stderr,syslog三个文件,排错通常只关注stderr。只要定位到具体的错误日志,问题总能迎刃而解。

  YARN的常见故障主要是进程挂掉,根据进程的重要性不同有不同的管理方案,详见进程管理部分。

  慢Job原因排查。在实践中,经常会有Hadoop集群的使用方遇到个别作 业执行很慢的情况,从而怀疑Hadoop是否有bug。事实证明,经过10余年的发展,Hadoop尤其是YARN在资源管理上已经相当严谨,99.999%的情况都是使用者的问题而非Hadoop本身bug。遇到慢Job可以从以下方面排查:
    ()整个Job慢还是个别Task慢,如果只有个别Task慢,首先排查数据偏斜 情况;
    ()哪个阶段慢,如果Job在开始执行前经历了很长的排队等待时间,要检查队列配置、申请资源量、当时集群的整体情况,查清没有分配资源的原因是什么;
    ()如果是Hive或Spark SQL慢,多从SQL书写方面找原因, 尤其是分区表没用分区、连接写错、过滤执行太晚都是非常常见的情况;
    ()其他情况,结合日志去排查,网络异常、权限问题、数据源端或目的端 阻塞等也可能造成作业慢。总之,MapReduce on YARN虽然是个以慢著称 的框架,但一定是慢得有理有据,如果搞不清慢的原因,即使换一个更快 的框架比如Spark,依然会遇到大量莫名其妙的慢问题。

四.进程管理

  我们只关注MRv2(MapReduce on YARN)涉及的进程。MRv1的进程管理 (jobtracker,tasktracker)已经过时,我们不需要了解。 

1>.YARN进程管理中,NodeManager(NM)的进程比较次要,死掉只需处理 完问题再拉起即可。

2>.ResourceManager(RM)负责YARN的资源管理和应用程序调度,是YARN 中最重要的进程,也是一个存在单点故障的进程。 

RM死掉后,我们需要立即拉起,默认情况下,在RM死掉前还没有运行完的 YARN应用都会失败,需要再次手工提交。YARN有一个参数 (yarn.resourcemanager.recovery.enabled)可以控制RM重启特性,如 果将其设置为true,则RM会使用某种状态存储来保存当前应用/应用的 attempt的信息,使得在重启RM后可以恢复这部分信息,作业可以接着运 行,而无需手工提交。

当然这一特性在Hadoop社区中分为两个阶段实现, 分别为2.4以前的实现和2.6以后的实现,可以在以下网址 (http://hadoop.apache.org/docs/r2.6.5/hadoop-yarn/hadoop-yarn-site/ResourceManagerRestart.html) 看到说明。两者的区别在于恢复过程中现有AM是否需要被杀死。需要注意 的是,该特性并不能解决RM的单点问题,只能使得RM的停机对用户无感知。 真正能解决RM单点故障的是RM HA特性,可以在以下网址 (http://hadoop.apache.org/docs/r2.6.5/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html) 看到说明。该方案使用zookeeper的临时节点来监控RM的活性,一旦临时 节点消失即可切换到standby RM,和NameNode HA中使用zk做切换的方式是类似的。 

3>.YarnChild、ApplicationMaster等进程都是由NM启动的,用户控制不 了,一旦这些进程挂掉,作业的一部分或全部就会宣告失败。此时需要参 照故障管理中的套路排查故障。 

五.配置管理

1>.MapReduce on YARN的主要配置的说明已介绍过,其余配置可查询官方 文档 

  MapReduce 参考链接:http://hadoop.apache.org/docs/r2.6.0/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml

  YARN 参考链接:http://hadoop.apache.org/docs/r2.6.0/hadoop-yarn/hadoop-yarn-common/yarn-default.xml

2>.需要注意的是大部分配置需要重启YARN服务生效,小部分需要重启单个NM节点生效。 

3>.对YARN日常维护中常用的命令总结如下

YARN用户命令
运行yarn程序(yarn jar)
对yarn程序查询状态、杀死、移动队列等(yarn application)
查看yarn程序的container日志(yarn logs)
其他(如yarn applicationattempt,yarn node等)   YARN管理命令
RM管理命令,如刷新队列配置、刷新节点信息、刷新管理员ACL权限、切
换RM的主备等(yarn rmadmin)
其他(主要用于启动yarn的进程,如yarn resourcemanager,yarn nodemanager等)  

六.课后作业

复习scheduler的知识 

熟悉本讲列举的配置项 

起一些MR作业,练习yarn application、yarn logs等命令 

实验配置ResourceManager HA