【发布时间】:2015-04-14 10:50:14
【问题描述】:
我正在从 Storm 的传统拓扑转移到 Trident 拓扑,后者在将元组推送到数据库之前维护成批的元组。我们将 XML 处理为单个元组。在一次处理一个 xml 的传统拓扑中,这很好用。但是在 Trident 拓扑中,在提交到数据库之前,它会在内存中保留大量元组,这会导致内存不足异常。也不清楚风暴如何决定批量大小以及它在每次迭代中的变化。以下是我们收到的错误:
java.lang.OutOfMemoryError:java.lang.AbstractStringBuilder 的 java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130) 的 java.util.Arrays.copyOf(Arrays.java:2367) 超出了 GC 开销限制。 ensureCapacityInternal(AbstractStringBuilder.java:114) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415) at java.lang.StringBuilder.append(StringBuilder.java:132) at clojure.core$str$fn__3896.invoke(core .clj:517) at clojure.core$str.doInvoke(core.clj:519) at clojure.lang.RestFn.invoke(RestFn.java:423) at backtype.storm.daemon.executor$mk_task_receiver$fn__5564.invoke( executor.clj:397) 在 backtype.storm.disruptor$clojure_handler$reify__745.onEvent(disruptor.clj:58) 在 backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:125) 在 backtype.storm.utils.DisruptorQueue .consumeBatchWhenAvailable(DisruptorQueue.java:99) at backtype.storm.disruptor$consume_batch_when_available.invoke(disruptor.clj:80) at backtype.storm.daemon.execut或 $fn__5641$fn__5653$fn__5700.invoke(executor.clj:746) at backtype.storm.util$async_loop$fn__457.invoke(util.clj:431) at clojure.lang.AFn.run(AFn.java:24)在 java.lang.Thread.run(Thread.java:745)
更多信息:
在处理螺栓时,我们使用 DOM 解析器来解析 XML。我们试图通过将 XML 的单个元素作为一个元组来减小单个元组的大小,但这也无济于事。
可能的解决方案可能包括限制存储在内存中的批次大小或采用快速垃圾收集。
【问题讨论】:
-
垃圾收集器的问题很棘手。见this reference。您正在使用哪些内存选项?您可能可以稍微调整一些值,但无论如何,除非您的内存选项确实有问题,否则错误的原因必须与创建无法删除的内存对象负载有关......您使用的代码是您的吗?
-
您应该能够使用 kafkaConfig 设置 bufferSizeBytes 和 fetchSizeBytes 来控制批量大小。见czcodezone.blogspot.com/2014/12/…
标签: xml out-of-memory apache-storm apache-kafka trident