这期内容当中小编将会给大家带来有关如何解决JobTracker Heap的OOM问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
引子
最近新上了9107渠道的实验。
从实验方法上,相比于之前的9105渠道只是简单地对过去6小时的正例数据进行翻倍,9107则以当前时间为基准,使用指数函数对合并后训练数据中的正例进行增益。
从具体的实现而言,为了实现的简单,实验的ETL部分依旧沿用Hadoop进行ETL合并处理,但后续的Sampling和Filtering则采用python单机实现。经过流程和数据测试无误后上线,但结果老集群的JobTracher总是在跑了70多个Job之后就报出Heap OOM异常(java.lang.OutOfMemoryError: Java heap space)。
解决过程
直接google
在statckoverflow中有人建议调整HADOOP_CLIENT_OPT,通过增大其Xmx解决该问题,经过尝试后发现无效果。
突然发现java_pidxxxxx.hprof文件,搜索相关资料,发现Eclipse中的MAT工具,分析可能为JT的问题
hprof为当虚拟机中发生OOM错误时,自动对Heap进行转储生成的二进制文件。在启动进程时,可以通过添加参数-XX:+HeapDumpOnOutOfMemoryError开启该功能。
MAT(Memory Analyzer)为Eclipse中一分析hprof文件的工具,可以通过Eclipse中的'Install New Software'进行集成。需要注意的一点是,当生成的hprof文件过大的时候,需要适当增大eclipse的启动Xmx,其配置文件为安装目录下的eclipse.ini。
通过MAT打开生成的hprof文件,如下图所示,会给出几条Problem Suspect,在本文中,说明是由于JobTracker的占用内存过大导致的OOM。
但是之前JobTracker稳定运行了好长时间,很少发生过该种现象,所以继续尝试使用MAT进行进一步的分析。通过对'dominator tree'一项进行分析发现,JobTracker中绝大部分的内存都是由JobInProgress占用的,其结果如下图所示。
至此,问题算是已经定位出来,但是之前的JobTracker跑了上千的Job也从来没有发生过该种问题,为什么这次只跑了70+个Job就发生了这种情况。
翻阅"Hadoop技术内幕",了解JobTracker的主要作用
google搜索并没有这方面很好地解答,就找了"Hadoop技术内幕"一书中关于JobTracker的一章节进行学习。有一点特别引起了我的注意,原来JobTracker在启动的时候会启动一些重要的线程和服务,其中有一个retireJobsThread线程。
对于retireJobsThread线程而言,它可以清理长时间驻留在内存的已经运行结束的Job信息(即JobInProgress对象的信息)。而将JobInProgress对象保存在内存中,则是为了方便外部对历史的Job信息进行查询。但由于JobInProgress对象会占用过多的内存,所以当Job同时满足条件a,b或是a,c时,就会被标志为过期的作业。
Job已经完成,即状态为SUCCEEDED,FAILED或KILLED
Job完成时间距离当前已经24小时(可以通过mapred.jobtracker.retirejob.interval调整)
Job拥有者已完成的Job数量大于100(可以通过mapred.jobtracker.completeuserjobs.maximum调整)
显然正是由于Job的retire机制,避免了JobTracker占用内存的无线膨胀。虽然解决了JobTracker占用内存的无限膨胀问题,但是为什么之前的JobTracker就能维护100个JobInProgress,而现在就不可以了呢?9105和9107渠道到底差到了什么地方了呢?
突然间,想到了是不是由于ETL Job占用的内存信息过大,导致当前2G的HeapSize放不下这100条JobInProgress信息呢。于是,将hadoop-env.sh中的HADOOP_HEAPSIZE从2000调整到了4000,问题神奇的就没有再出现过。那么究竟是为什么ETL Job会比Sampling Job和Filtering Job占用更多的内存呢?于是就有了最后一步...
实际实验测试,使用jmap生成hprof文件,分析与预期的结果
在集群平稳的运行了100+个Job之后,使用jmap工具dump出来了一份JobTracker的hprof文件。再次使用MAT对其进行分析,结果如下图所示:
由图可以看出以下几点:
JobTracker的内存占用一直保持在1.7G左右
针对于JobInProgress占用内存过大的原因,完全是由于其需要调度的TaskInProgress过多(一般为2K-3K个),从而比Sampling和Filtering耗费掉更多的内存
至此,问题解决,确实是因为9107渠道只保留了9105渠道的ETL Job,导致多个ETL JobInPregress累计占用内存远大于之前的9105实验,从而造成JobTracker一直产生OOM错误。
心得总结
说起来,问题的解决多多少少还是存在一定的偶然性,归根结底还是在于对Hadoop平台一些基础组件的底层实现不熟悉,从而导致问题定位慢,走了不少的弯路
MAT确实是一个特别强大的工具,针对于JVM的OOM错误而言,通过使用MAT能够非常方便的定位问题的根结。后续对MAT的学习使用还需要进一步的加强。
对于正常运行中的java进程,可以使用jmap的jmap -dump:format=b,file=xx pid命令生成hprof文件,从而分析某一时刻进程中内存的详细使用情况
上述就是小编为大家分享的如何解决JobTracker Heap的OOM问题了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。