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

重磅 解决 hadoop job 卡死 根源问题,第1张

做大数据&&算法 其实最重要的三件事 ,就是 管理数据 和集群运维 模型训练,一旦 远离这三个主题,大数据都无法发挥它应用的作用。

废话不多说,这几天主要是采坑了。我认为现在碰到的最要命的就是 碰到 集群 掉链此粗子 无法使用,导致 其他 同事无法运行 任务。

这几天,碰到了两次 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 属性对应的 磁盘目录

一、首先要知道此前提转载若在windows的Eclipse工程中直接启动mapreduc程序,需要先把hadoop集群的配置目录下的xml都拷贝到src目录下,让程序自动读取集群的地址后去进行分布式运行(您也可以自己写java代码去设置job的configuration属性)。若不拷贝,工程中bin目录没有完整的xml配置文件,则windows执行的mapreduce程序全部通过本机的jvm执行,作业名也是带有“local"字眼的作业,如job_local2062122004_0001。这不是真正的分布式运行mapreduce程序。估计得研究org.apache.hadoop.conf.Configuration的源码,反正xml配置文件会影响执行mapreduce使用的文件系统是本机的windows文件系统还是远程的hdfs系统还有影响执行mapreduce的mapper和reducer的是本机的jvm还是集群里面机器的jvm二、本文的结论第一点就是:windows上执行mapreduce,必须打jar包到所有slave节点才能正确分布式运行mapreduce程序。(我有个需求是要windows上触发一个mapreduce分布式运行) 饥庆 第二点就是:Linux上,只需拷贝jar文件到集群master上,执行命令hadoopjarPackage.jarMainClassName即可分布式运行mapreduce程序。第三点就是:推荐使用附一,实现了自动打jar包并上传,分布式执行的mapreduce程序。附一、推荐使用此方法:实现了自动打jar包并上传,分布式执行的mapreduce程序:请先参考博文五篇:Hadoop作业提交分析(一)~~(五)引用博文的附件中EJob.java到你的工程中,然后main中添加如下方法和代码。publicstaticFilecreatePack()throwsIOException{FilejarFile=EJob.createTempJar("bin")ClassLoaderclassLoader=EJob.getClassLoader()Thread.currentThread().setContextClassLoader(classLoader)returnjarFile}在作业烂棚握启动代码中使用打包:和空Jobjob=Job.getInstance(conf,"testAnaAction")添加:StringjarPath=createPack().getPath()job.setJar(jarPath)即可实现直接runasjavaapplication在windows跑分布式的mapreduce程序,不用手工上传jar文件。附二、得出结论的测试过程(未有空看书,只能通过愚笨的测试方法得出结论了)一.直接通过windows上Eclipse右击main程序的java文件,然后"runasapplication"或选择hadoop插件"runonhadoop"来触发执行MapReduce程序的测试。1,如果不打jar包到进集群任意linux机器上,它报错如下:[work]2012-06-2515:42:47,360-org.apache.hadoop.mapreduce.Job-10244[main]INFOorg.apache.hadoop.mapreduce.Job-map0%reduce0%[work]2012-06-2515:42:52,223-org.apache.hadoop.mapreduce.Job-15107[main]INFOorg.apache.hadoop.mapreduce.Job-TaskId:attempt_1403517983686_0056_m_000000_0,Status:FAILEDError:java.lang.RuntimeException:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountMappernotfoundatorg.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)atorg.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)atorg.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:721)atorg.apache.hadoop.mapred.MapTask.run(MapTask.java:339)atorg.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)atjava.security.AccessController.doPrivileged(NativeMethod)atjavax.security.auth.Subject.doAs(Subject.java:415)atorg.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)atorg.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)Causedby:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountMappernotfoundatorg.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1626)atorg.apache.hadoop.conf.Configuration.getClass(Configuration.java:1718)8more#Error:后重复三次2012-06-2515:44:53,234-org.apache.hadoop.mapreduce.Job-37813[main]INFOorg.apache.hadoop.mapreduce.Job-map100%reduce100%现象就是:报错,无进度,无运行结果。2,拷贝jar包到“只是”集群master的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse"runasapplication"和通过hadoop插件"runonhadoop"来触发执行,它报错同上。现象就是:报错,无进度,无运行结果。3,拷贝jar包到集群某些slave的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse"runasapplication"和通过hadoop插件"runonhadoop"来触发执行和报错:Error:java.lang.RuntimeException:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountMappernotfoundatorg.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)atorg.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)和报错:Error:java.lang.RuntimeException:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountReducernotfound现象就是:有报错,但仍然有进度,有运行结果。4,拷贝jar包到集群所有slave的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse"runasapplication"和通过hadoop插件"runonhadoop"来触发执行:现象就是:无报错,有进度,有运行结果。第一点结论就是:windows上执行mapreduce,必须打jar包到所有slave节点才能正确分布式运行mapreduce程序。二在Linux上的通过以下命令触发MapReduce程序的测试。hadoopjar$HADOOP_HOME/share/hadoop/mapreduce/bookCount.jarbookCount.BookCount1,只拷贝到master,在master上执行。现象就是:无报错,有进度,有运行结果。2,拷贝随便一个slave节点,在slave上执行。现象就是:无报错,有进度,有运行结果。但某些节点上运行会报错如下,且运行结果。:14/06/2516:44:02INFOmapreduce.JobSubmitter:Cleaningupthestagingarea/tmp/hadoop-yarn/staging/hduser/.staging/job_1403517983686_0071Exceptioninthread"main"java.lang.NoSuchFieldError:DEFAULT_MAPREDUCE_APPLICATION_CLASSPATHatorg.apache.hadoop.mapreduce.v2.util.MRApps.setMRFrameworkClasspath(MRApps.java:157)atorg.apache.hadoop.mapreduce.v2.util.MRApps.setClasspath(MRApps.java:198)atorg.apache.hadoop.mapred.YARNRunner.createApplicationSubmissionContext(YARNRunner.java:443)atorg.apache.hadoop.mapred.YARNRunner.submitJob(YARNRunner.java:283)atorg.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:415)atorg.apache.hadoop.mapreduce.Job$10.run(Job.java:1268)atorg.apache.hadoop.mapreduce.Job$10.run(Job.java:1265)atjava.security.AccessController.doPrivileged(NativeMethod)atjavax.security.auth.Subject.doAs(Subject.java:415)atorg.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)atorg.apache.hadoop.mapreduce.Job.submit(Job.java:1265)atorg.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1286)atcom.etrans.anaSpeed.AnaActionMr.run(AnaActionMr.java:207)atorg.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)atcom.etrans.anaSpeed.AnaActionMr.main(AnaActionMr.java:44)atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)atjava.lang.reflect.Method.invoke(Method.java:606)atorg.apache.hadoop.util.RunJar.main(RunJar.java:212)第二点结论就是:Linux上,只需拷贝jar文件到集群master上,执行命令hadoopjarPackage.jarMainClassName即可分布式运行mapreduce程序。

ArrayWritable不能直脊御液樱物接作为mapreduce的输入输出类型。

程序不是卡住了,而是报错了。

估计是这个错误java.lang.RuntimeException: java.lang.NoSuchMethodException: org.apache.hadoop.io.ArrayWritable.<init>()

这个错误是ArrayWritable初始化异常,要自己实现一个ArrayWritable的派生类

如果是text类型的数组 For example: public class TextArrayWritable extends ArrayWritable { public TextArrayWritable() { super(Text.class)} }即可,在maprecude中用TextArrayWritable 替换掉ArrayWritable

A Writable for arrays containing instances of a class. The elements of this writable must all be instances of the same class. If this writable will be the input for a Reducer, you will need to create a subclass that sets the value to be of the proper type. For example: public class IntArrayWritable extends ArrayWritable { public IntArrayWritable() { super(IntWritable.class)} }

==========================

参拆森考:http://hadoop.apache.org/docs/current/api/org/apache/hadoop/io/ArrayWritable.html


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12352138.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-22
下一篇2023-05-22

发表评论

登录后才能评论

评论列表(0条)

    保存