长时间运行我的流数据流作业往往会导致超出GC开销限制"使工作停止的错误。我怎样才能最好地进行调试?
java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.google.cloud.dataflow.worker.repackaged.com.google.common.collect.HashBasedTable.create (HashBasedTable.java:76)
at com.google.cloud.dataflow.worker.WindmillTimerInternals.<init> (WindmillTimerInternals.java:53)
at com.google.cloud.dataflow.worker.StreamingModeExecutionContext$StepContext.start (StreamingModeExecutionContext.java:490)
at com.google.cloud.dataflow.worker.StreamingModeExecutionContext.start (StreamingModeExecutionContext.java:221)
at com.google.cloud.dataflow.worker.StreamingDataflowWorker.process (StreamingDataflowWorker.java:1058)
at com.google.cloud.dataflow.worker.StreamingDataflowWorker.access$1000 (StreamingDataflowWorker.java:133)
at com.google.cloud.dataflow.worker.StreamingDataflowWorker$8.run (StreamingDataflowWorker.java:841)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
at java.lang.Thread.run (Thread.java:745)
答案 0 :(得分:2)
我已经遇到过这个问题了几次。我的方法通常从尝试隔离导致Dataflow中的内存错误的转换步骤开始。这是一个较长的过程,但你通常可以做出有根据的猜测,哪个是有问题的变换。删除转换,执行管道,并检查错误是否仍然存在。
一旦我确定了有问题的转换,我就会开始考虑任何内存效率低下的实现。这通常与初始化对象(内存分配)或变换具有非常高扇出的设计有关;创造一堆输出。但它可能像字符串操作一样微不足道。
从这里开始,这只是继续孤立问题的问题。数据流确实存在内存限制。您可能会增加支持工作人员的Compute Engine实例的硬件。但是,这不是一个可扩展的解决方案。
您还应该考虑仅使用Apache Beam Java实现管道。这将排除Scio作为问题。但通常情况并非如此。