美文网首页hadoop
Yarn ResourceManager内存泄漏

Yarn ResourceManager内存泄漏

作者: guangdong_18b7 | 来源:发表于2018-03-09 20:12 被阅读0次

    问题描述:

             探索环境中的yarn的ResourceManager的内存随着使用时间不断的变大,最终导致用户无法访问yarn的资源管理页面,并且整个集群的调度变得异常缓慢,最终导致隔一段时间就需要重启一下Yarn。

    问题分析:

    1.最先想到的是由于内存泄漏导致,因此到集群上取Dump文件,最开始使用的是命令(jmap

    -dump:live,format=b,file=dump.hprof 22439)获取dump文件的,但是导致的一个结果就是把ResourceManager搞挂了,后来才知道是因为探索环境的yarn使用的是G1垃圾回收机制,对于G1垃圾回收机制,使用上面的方式可能会将进程搞挂掉,改成下面的命方式即可成功的获取dump文件:jmap-J-d64 -dump:live,format=b,file=yarn-22439.dump 22439  。

    2.通过对dump文件的内存泄漏检测分析,发现

    在类AsyncDispatcher中的一个属性(BlockingQueue eventQueue)的对象占用了大量的内存,因此怀疑是该对象发生了内存泄漏。

    3. 通过类AsyncDispatcher的源码,发现其内部类GenericEventHandler会在处理消息的时候将上面怀疑是内存泄漏的对象eventQueue的size打印出来,因此决定查看线上yarn的日志,看此队列的长度

    下图是列出的队列的长度,可明显可以看出该队列的尺寸达到了上千万,这肯定是有问题的。而正常的大集群的日志中队列的长度只有几千,很明显该对象是有问题的。

    4.再通过内存分析工具发现,上述有异常的队列中存放的都是ContainerFinishedEvent和ContainerCreatedEvent对象,因此去查看该对象是在哪被创建和消费的。

    5. 通过对源码进行分析定位到ContainerFinishedEvent事件是在类SystemMetricsPublisher中被消费掉的,该类是将ContainerFinishedEvent封装成TimelineEntity实体之后通过Http的post方式发送给yarn的TimelineServer进程。

    6. 综上分析,目前的主要原因是由于消费者(也就是往TimelineServer发送Event事件数据)发送数据的能力不够,导致消息队列中缓存的大量的消息,随着时间的推移,消息数据不断增多,从而导致yarn内存不够用,从而需要重启。

    问题的解决:

    方案一、

    通过分析SystemMetricsPublisher的源码发现,如下图中标记的的代码,可以控制是否向TimelineServer发送测量数据,标记的代码对应的参数的值为:

    yarn.timeline-service.enabled 和 yarn.system-metrics-publisher.enabled

    于是将yarn.system-metrics-publisher.enabled的值设置为false,也就是关闭了发送测量数据的功能,问题解决。

    方案二、

    通过分析SystemMetricsPublisher的源码发现,在创建分发器的时候,有个参数(yarn. system-metrics-publisher.dispatcher.pool-size ,默认值为10)可以控制发送的线程池的数量,通过增大该值,理论上应该也是可以解决该问题的,但没有具体测试,因为是线上环境。

    相关文章

      网友评论

        本文标题:Yarn ResourceManager内存泄漏

        本文链接:https://www.haomeiwen.com/subject/ohymfftx.html