trident拓扑抛出内存不足异常

zqdjd7g9  于 2021-06-08  发布在  Kafka
关注(0)|答案(2)|浏览(507)

我正在从storm的传统拓扑结构转向trident拓扑结构,trident拓扑结构在将元组推送到数据库之前维护成批元组。我们将xml作为一个元组进行处理。在一次处理一个xml的传统拓扑中,这种方法很好地工作。但在trident拓扑中,在提交到数据库之前,它在内存中保留了大量元组,这导致了内存不足异常。目前还不清楚storm是如何决定批量大小的,它在每次迭代中都会发生变化。以下是我们收到的错误:
java.lang.outofmemoryerror:超出java.util.arrays.copyof(arrays)的gc开销限制。java:2367)在java.lang.abstractstringbuilder.expandcapacity(abstractstringbuilder。java:130)在java.lang.abstractstringbuilder.ensurecapacityinternal(abstractstringbuilder。java:114)在java.lang.abstractstringbuilder.append(abstractstringbuilder。java:415)在java.lang.stringbuilder.append(字符串生成器。java:132)在clojure.core$str$fn\uu3896.invoke(core。clj:517)在clojure.core$str.doinvoke(core。clj:519)在clojure.lang.restfn.invoke(restfn。java:423)在backtype.storm.daemon.executor$mk\u task\u receiver$fn\uu 5564.invoke(executor。clj:397)在backtype.storm.disruptor$clojure\u handler$reify\u 745.onevent(disruptor。clj:58)在backtype.storm.utils.disruptorqueue.consumebatchtocursor(disruptorqueue。java:125)在backtype.storm.utils.disruptorqueue.consumebatchwhenavailable(disruptorqueue。java:99)在backtype.storm.disruptor$consume\u batch\u when\u available.invoke(disruptor。clj:80)在backtype.storm.daemon.executor$fn\uu5641$fn\u5653$fn\u5700.invoke(executor。clj:746)在backtype.storm.util$async\u loop$fn\u 457.invoke(util。clj:431)在clojure.lang.afn.run(afn。java:24)在java.lang.thread.run(线程。java:745)
更多信息:
在处理螺栓时,我们使用dom解析器来解析XML。我们试图通过将xml的单个元素作为一个元组来减小单个元组的大小,但也没有任何帮助。
可能的解决方案包括限制存储在内存中的批大小或采用快速垃圾收集。

xam8gpfp

xam8gpfp1#

java.lang.outofmemoryerror:超出gc开销限制
以下是异常的原因
详细消息“gc overhead limit exceeded”表示垃圾收集器一直在运行,java程序进展非常缓慢。在垃圾收集之后,如果java进程花费大约98%以上的时间进行垃圾收集,并且恢复的堆不到2%,并且一直在进行最后5次(编译时常量)连续垃圾收集,则抛出java.lang.outofmemoryerror。抛出此异常通常是因为活动数据量几乎无法放入java堆,而新分配的可用空间很小。
详情可在这里找到
http://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks.html
这个问题的真正原因是应用程序内存使用量的增加,而gc无法清除足够的内存以使应用程序继续工作,因此在抛出oome(java.lang.outofmemoryerror:java heap space)之前,jvm会抛出这个问题。我已经做了很多jvm的调优等等,但是从来没有看到过这个消息,因为我可能已经用jvm的旧版本做了调优,而这个版本没有发出这个消息。
从逻辑上讲,有两种可能看到此消息-应用程序正在泄漏内存。-应用程序正在消耗更多内存。
对于前一种情况,需要修复内存泄漏,方法是分析heapdump并检查消耗内存的内容,确保它不是泄漏。heapdump可以使用eclipse mat进行分析,我个人使用过它。
对于后面的情况,您将不得不增加堆的大小,这也在我上面粘贴的链接中进行了解释,您需要执行以下操作
措施:增加堆大小。对于超出gc开销限制的java.lang.outofmemoryerror异常,可以使用命令行标志-xx:-usegcoverheadlimit关闭。

t2a7ltrp

t2a7ltrp2#

我可以通过如下设置kafka fetch size和buffer size来控制每次迭代中的批大小:

spoutConf.fetchSizeBytes = 5*1024*1024;
    spoutConf.bufferSizeBytes = 5*1024*1024;

这限制了内存中保存的数据量。我们必须根据您的用例来调整这个限制,这样内存中的数据对于您的系统来说不会太大,但是系统可以提供最大的吞吐量。

相关问题