重磅 解决 hadoop job 卡死 根源问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重磅 解决 hadoop job 卡死 根源问题相关的知识,希望对你有一定的参考价值。

参考技术A 做大数据&&算法 其实最重要的三件事 ,就是 管理数据 和集群运维 模型训练,一旦 远离这三个主题,大数据都无法发挥它应用的作用。
废话不多说,这几天主要是采坑了。我认为现在碰到的最要命的就是 碰到 集群 掉链子 无法使用,导致 其他 同事无法运行 任务。

这几天,碰到了两次 hadoop mapreduce 卡死的现象 ,主要就是停留在 job 那里 无法进行,或者map 0 reduce 0.第一次 碰到时没有找到原因,用网上最粗暴的方法 重启了hadoop集群,暂时解决了问题。
今天又碰到了同样的问题,因为 logstash一直在往hdfs上写数据,一旦重启集群可能会丢失数据,所以 一直非常谨慎,不敢 行事。希望找到最主要的原因。通过在网上查找,其实大部分是三种
1.原先配置有严重错误问题,因为之前我的集群 运行良好,现在 卡死,可能是 最近 集群状态除了问题可以排除这一条,还有就是程序本身有问题,因为同一个程序运行小数据量的正常出了结果,大数据量就job卡死掉了,说明程序本身没有问题
2.剩下的两天就是 磁盘不足了和内存 不足了
先说磁盘不足 ,其实这个是半真半假的事情,我们三个 DataNode节点的 各有 12T 的数据存放 磁盘,12块1024G的磁盘构成,但是 系统盘 只有区区 60G,
内存不足 ,也是一个半真半假的事情,每个节点 12G 内存,三个节点36G,每个节点 cpu 六核。
为了确定问题的根源,只能先看 hadoop的logs 日志,Master 和 DataNode的logs 都看了,但是都没有找到具体的原因,有点沮丧,后来 就去分析 job 执行 的网页状态,job状态也没有发现太多问题,因为 job卡死,很多job 就直接被 hadoop job -kill job_id 掉了
后来就看 集群状态图,发现一些猫腻。 CPU total 变成0 了,memery也是 0,接着再看,发现 node unhealthy 出现了 3,

点开一看,三个数据节点都是unhealthy的。

那么 这个unhealthy 是一个更明晰的问题特征,

接着就跟着往深里 找原因,出现 unhealthy 两种原因,1. 节点通信故障 ,因为hdfs 一直在写数据 很正常,可以排除
2。磁盘 真的 不足了,但是我的节点12个磁盘都是在没有超过80%呀,只有系统盘超过了90%,难道 hadoop 连系统盘都算是检查的盘,好吧,可能是,之后就按网上的以解决磁盘不足导致job卡死。

主要是 hadoop 默认检查 磁盘状况,一旦超过默认的90%就会 导致 数据节点拒绝执行mapreduce,通过在yarn-site.xml 设置 更大的阈值,延迟 节点拒绝mapreduce的情况。通过在其中添加
<property> <name>yarn.nodemanager.disk-health-checker.min-healthy-disks</name> <value>0.0</value> </property> <property> <name>yarn.nodemanager.disk-health-checker.max-disk-utilization-per-disk-percentage</name> <value>100.0</value> </property>
集群也没有重启,Master和数据节点 四个机器都修改了,然后就生效。所以说 有些配置可以不重启集群实现的。
如果要重启,网上给出 只用重启 NodeManager 和Resourcemannager
`
3.1 重启nodemanager:

/usr/local/goldmine/hadoop/default/sbin/yarn-daemon.sh stop nodemanager

/usr/local/goldmine/hadoop/default/sbin/yarn-daemon.sh start nodemanager

3.2 重启resourcemanager,(否则会导致修改的节点状态错乱)

/usr/local/goldmine/hadoop/default/sbin/yarn-daemon.sh stop resourcemanager

/usr/local/goldmine/hadoop/default/sbin/yarn-daemon.sh start resourcemanager

3.3 刷新 http://hadoop/cluster/nodes/unhealthy 页面: 可以看到不健康的nodemanager已经消失在列表了。3.4 命令显示yarn各节点状态:
yarn node -list -all

`
也定位到了原来是系统磁盘惹得鬼,下次在建hadoop集群,系统磁盘也一定要足够大,不然会严重影响集群的稳定。
之后执行job 完美执行了,再看系统盘也恢复到40%一下,刚才主要是系统盘有一些【临时文件】导致的。

之后发现 job 又卡死了,但是这次是卡死在 map12 reduce0中,好诡异,之前 发生了一件事情,map60% 后,竟然回滚了到了map 0,接着卡死。再次查看系统盘,又 飙到了97% 99% 96%,因为系统盘无法 扩容,这可咋整。

那我们就要想想 为什么 系统盘会突然猛增大量的临时文件 挤占磁盘空间,为什么 为什么!!!!!!,想了半天我终于知道了,这和hadoop的mapreduce 原理有关,如果是spark就不会出现这种情况,更多的是内存不足,hadoop 的mapreduce 在map的中间结果会保留在磁盘上,而spark的中间结果会放在内存里,所以更快更吃内存。
正是因为hadoop的中间结果保存在了磁盘上,导致猛增大量临时文件。好,现在问题的根源找到了,就是mapreduce 的中间文件太大影响了 磁盘空间 导致节点拒绝服务,内存 和CPU 拒绝提供 都为 0, 导致 没有资源,job 卡死。也说明了,为啥 小数据量程序正常,大数据量了反而 job卡死,正是因为 数据量越大 中间结果就更多,挤占磁盘就更多。

但是我们 执行mapreduce就是要产生中间文件的,这个是源码规定 适合hadoop运行保障的,不可以修改,那么 既然中间临时文件必须产生,主要就是把中间文件放在哪里,可以保障 挤占磁盘的百分比更小,当然是更大的磁盘了,我们的最小磁盘是系统盘,所以最容易增长百分比,job卡死,所以我们要用最大的盘 保留 中间结果,我们最大的盘是1024G,就用这个就可以了,然后就是设置 mapreduce中间结果路径,在配置文件里,到这里,问题就等于从根源上解决了。
hadoop 2.8.1 需要在 mapred-site.xml 设置 map.local.dir 和
map.tmp.dir 属性对应的 磁盘目录

Hadoop常见异常及其解决方式


1、Shell$ExitCodeException

现象:执行hadoop job时出现例如以下异常:

14/07/09 14:42:50 INFO mapreduce.Job: Task Id : attempt_1404886826875_0007_m_000000_1, Status : FAILED
Exception from container-launch: org.apache.hadoop.util.Shell$ExitCodeException: 
org.apache.hadoop.util.Shell$ExitCodeException: 
        at org.apache.hadoop.util.Shell.runCommand(Shell.java:505)
        at org.apache.hadoop.util.Shell.run(Shell.java:418)
        at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:650)
        at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:195)
        at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:300)
        at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:81)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

Container exited with a non-zero exit code 1

原因及解决的方法:原因未知。

重新启动可恢复正常


2、libhadoop.so.1.0.0 which might have disabled stack guard

现象:Hadoop 2.2.0 - warning: You have loaded library /home/hadoop/2.2.0/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard.

原因及解决方法:
在/etc/profile中加入:
#hadoop configuration
export PATH=$PATH:/home/jediael/hadoop-2.4.1/bin:/home/jediael/hadoop-2.4.1/sbin
export HADOOP_HOME=/home/jediael/hadoop-2.4.1
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib"
此警告出现的原因是最后2项未加入。


3、Retrying connect to server: master166/10.252.48.166:9000. Already tried 0 time(s)

在datanode上运行hdfs相关命令时,出现下面错误:

[[email protected] ~]$ hadoop fs -ls /
14/08/31 15:00:37 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:38 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 1 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:39 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 2 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:40 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 3 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:41 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 4 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:42 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 5 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:43 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 6 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:44 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 7 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:45 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 8 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
14/08/31 15:00:46 INFO ipc.Client: Retrying connect to server: master166/10.252.48.166:9000. Already tried 9 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1 SECONDS)
ls: Call to master166/10.252.48.166:9000 failed on connection exception: java.net.ConnectException: Connection refused

出现以上错误,通常都是因为datanode无法连接到namenode所致,下面是一种情况:

/etc/hosts中存在127.0.0.1 *****的配置,如

127.0.0.1 localhost

将这些配置去掉,然后又一次格式化namenode。并重新启动hadoop进程就可以解决。

或者是下面原因:

hadoop安装完毕后,必需要用haddop namenode format格式化后,才干使用,假设重新启动机器

在启动hadoop后,用hadoop fs -ls命令老是报 10/09/25 18:35:29 INFO ipc.Client: Retrying connect to server: localhost/127.0.0.1:9000. Already tried 0 time(s).的错误,

用jps命令。也看不不到namenode的进程。 必须再用命令hadoop namenode format格式化后。才干再使用

    原因是:hadoop默认配置是把一些tmp文件放在/tmp文件夹下,重新启动系统后,tmp文件夹下的东西被清除。所以报错

    解决方法:在conf/core-site.xml 中添加下面内容

   <property>

   <name>hadoop.tmp.dir</name>

   <value>/var/log/hadoop/tmp</value>

  <description>A base for other temporary directories</description>

  </property>

  重新启动hadoop后,格式化namenode就可以


4、Permission denied: user=liaoliuqing, access=WRITE, inode="":jediael:supergroup:rwxr-xr-x

原由于用户权限不足,能能訪写HDFS中的文件。

解决方式:

关闭hadoop权限。在hdfs-site.xml文件里加入

<property>    

<name>dfs.permissions</name>    

<value>false</value>    

</property>


5、Incompatible namespaceIDs

2015-02-02 15:10:57,526 INFO org.apache.hadoop.metrics2.impl.MetricsConfig: loaded properties from hadoop-metrics2.properties
2015-02-02 15:10:57,543 INFO org.apache.hadoop.metrics2.impl.MetricsSourceAdapter: MBean for source MetricsSystem,sub=Stats registered.
2015-02-02 15:10:57,543 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: Scheduled snapshot period at 10 second(s).
2015-02-02 15:10:57,544 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: DataNode metrics system started
2015-02-02 15:10:57,699 INFO org.apache.hadoop.metrics2.impl.MetricsSourceAdapter: MBean for source ugi registered.
2015-02-02 15:10:58,090 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Incompatible namespaceIDs in /mnt/tmphadoop/dfs/data: namenode namespaceID = 2017454015; datanode namespaceID = 1238467850
        at org.apache.hadoop.hdfs.server.datanode.DataStorage.doTransition(DataStorage.java:232)
        at org.apache.hadoop.hdfs.server.datanode.DataStorage.recoverTransitionRead(DataStorage.java:147)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.startDataNode(DataNode.java:414)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.<init>(DataNode.java:321)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.makeInstance(DataNode.java:1712)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.instantiateDataNode(DataNode.java:1651)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.createDataNode(DataNode.java:1669)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.secureMain(DataNode.java:1795)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.main(DataNode.java:1812)

问题原因:
每次namenode format会又一次创建一个namenodeId,而${hadoop.tmp.dir}/dfs/data下包括了上次format下的id,当又一次运行namenode format时清空了namenode下的数据,可是没有清空datanode下的数据,所以造成namenode节点上的namespaceID与 datanode节点上的namespaceID不一致,从而导致从现上述异常,启动失败。


解决的方法:
(1)停止hadoop
 stop-all.sh
(2)在各个slave中删除dfs.data.dir中的内容。

若此属性未改动。则其默认值为
<property>
  <name>${dfs.data.dir}</name>
  <value>${hadoop.tmp.dir}/dfs/data</value>
  <description>Determines where on the local filesystem an DFS data node
  should store its blocks.  If this is a comma-delimited
  list of directories, then data will be stored in all named
  directories, typically on different devices.
  Directories that do not exist are ignored.
  </description>
</property>
(3)又一次格式化namenode
hadoop namenode -format
然后start-all.sh启动hadoop

以上解决的方法须要将原有数据删除,若数据不能删除。则使用下面方法之中的一个:
(1)改动${dfs.data.dir}/current/VERSION文件。将datanode中的id改成与namenode中的id一致。


(2)改动${dfs.data.dir}

































































































以上是关于重磅 解决 hadoop job 卡死 根源问题的主要内容,如果未能解决你的问题,请参考以下文章

使用ls / 命令卡死,或者df -h 查看卡死解决办法

关于 eclipse启动卡死的问题 解决方法

Ubuntu 16.04中XMind 8导致Java内存溢出的问题解决(硬盘卡死,桌面卡死)

Oracle登录卡死监听设置卡死,查询非常慢等原因解决办法

关于Ubuntu18.04谷歌浏览器经常卡死的解决

怎么解决Android studio导入项目卡死