YARN维护管理

我们只关注MRv2(MapReduce on YARN)涉及的进程。MRv1的进程管理 (jobtracker,tasktracker)已经过时,我们不需要了解。
YARN进程管理中,NodeManager(NM)的进程比较次要,死掉只需处理 完问题再拉起即可。
ResourceManager(RM)负责YARN的资源管理和应用程序调度,是YARN 中最重要的进程,也是一个存在单点故障的进程。
RM死掉后,我们需要立即拉起,默认情况下,在RM死掉前还没有运行完的 YARN应用都会失败,需要再次手工提交。YARN有一个参数 (yarn.resourcemanager.recovery.enabled)可以控制RM重启特性,如 果将其设置为true,则RM会使用某种状态存储来保存当前应用/应用的 attempt的信息,使得在重启RM后可以恢复这部分信息,作业可以接着运 行,而无需手工提交。
当然这一特性在Hadoop社区中分为两个阶段实现, 分别为2.4以前的实现和2.6以后的实现,
两者的区别在于恢复过程中现有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做切换的方式是类似的。
YarnChild、ApplicationMaster等进程都是由NM启动的,用户控制不了,一旦这些进程挂掉,作业的一部分或全部就会宣告失败。此时需要参照故障管理中的套路排查故障。
故障管理
MRv2日常维护的一个重要部分是处理MapReduce作业(包括Hive作业) 的各种错误。错误类型繁多,这里列举最为常见的几种:
AccessControlException: Permission denied
MR作业运行时需要向HDFS写入临时数据,运行完后也可能需要将最终结果 写入HDFS。如果运行MR作业的账号对指定目录没有写入权限,即抛出 AccessControlException异常。这种情况在开启了Kerberos认证的集群上 更容易出现。解决方案也很简单,给目录足够的权限,或改变运行账号。
ClassNotFoundException
该异常通常是因为没有找到运行MR作业所需的jar包,使得代码中引用的 某些类找不到。该问题在调试时尤其常见,在代码上线后应该不会出现, 除非有人破坏了CLASSPATH。解决方法是,将所需jar包加入CLASSPATH, 或将所需jar包直接打在MR作业的jar包中。
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,就要从代码层面寻找原因,排除过度使用堆内存的隐患。
Task的栈内存溢出,java.lang.StackOverflowError
比较罕见,通常是因为递归调用、调用链太长导致的。该问题需要从代码层面排除。
ApplicationMaster堆内存溢出
在MRv2中比较罕见,通常是因为输入数据太大,或指定的map数太多,使得AM的内存不足以管理如此多的map。
解决方法:
将“yarn.app.mapreduce.am.resource.mb”调大。另外该问题在Spark on YARN 时出现的可能性大,此时Spark Driver相当于AM,如果执行Spark Streaming并有很多个微批延时,容易出现Driver内存溢出的情况
非堆内存溢出,java.lang.OutOfMemoryError:Direct buffer memory
这种情况在MRv2中也较罕见(Spark on YARN时较多),原因是在代码中 使用了NIO等会使用非堆内存的特性。解决该问题还是要从代码层面优化。
ClassCastException: org.apache.hadoop.io.XXX cannot be cast to org.apache.hadoop.io.XXX
典型的类型转换错误,通常出现在Java实现的MR程序中,mapper和 reducer的输入输出类型是有一定限制的,比如mapper的第一个参数类型 必须是LongWritable或NullWritable,mapper的输出类型必须和reducer 的输入类型一致,否则就会出现此类问题。解决办法是调整代码。
java.io.IOException
出现该异常的场景很多,如读写HDFS错误、RPC请求超时、网络配置错误 等。需要根据更细节的信息(如异常堆栈)进一步排查,通常都是比较明 显的错误。
其他错误
通过日志排查。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可以从以下方面排查:
(1)整个Job慢还是个别Task慢,如果只有个别Task慢,首先排查数据偏斜 情况;
(2)哪个阶段慢,如果Job在开始执行前经历了很长的排队等待时间,要检查队列配置、申请资源量、当时集群的整体情况,查清没有分配资源的原因是什么;
(3)如果是Hive或Spark SQL慢,多从SQL书写方面找原因, 尤其是分区表没用分区、连接写错、过滤执行太晚都是非常常见的情况;
(4)其他情况,结合日志去排查,网络异常、权限问题、数据源端或目的端 阻塞等也可能造成作业慢。总之,MapReduce on YARN虽然是个以慢著称 的框架,但一定是慢得有理有据,如果搞不清慢的原因,即使换一个更快 的框架比如Spark,依然会遇到大量莫名其妙的慢问题。
posted @ 2025-06-21 22:12  屠魔的少年  阅读(23)  评论(0)    收藏  举报