如何解决JobTracker Heap的OOM问题

如何解决JobTracker Heap的OOM问题

这期内容当中小编将会给大家带来有关如何解决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时,就会被标志为过期的作业。

      1. Job已经完成,即状态为SUCCEEDED,FAILED或KILLED

      2. Job完成时间距离当前已经24小时(可以通过mapred.jobtracker.retirejob.interval调整)

      3. 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对其进行分析,结果如下图所示:

    由图可以看出以下几点:

      1. JobTracker的内存占用一直保持在1.7G左右

      2. 针对于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问题了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注恰卡编程网行业资讯频道。

发布于 2021-12-23 21:19:05
收藏
分享
海报
0 条评论
56
上一篇:怎么分析Zookeeper的一致性 下一篇:如何实现zookeepr分析
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码