2016-07-23 3 views
1


私はデータフローを使用していますが、ユーザーIDリストをコンマで区切って文字列を作成する必要があります。そして結果をGCSで書く。
残念ながら、DoFnのprocessElementでは、各行には多くのユーザーが存在し、java.lang.OutOfMemoryErrorという結果になります。
OutOfMemory例外を回避し、テキストファイルを含むGCSの各行に大量の行を正常に書き込む方法はありますか?
私のソースコードは以下の通りです。ソースコードここprocessElementの出力がfatである場合のメモリ不足例外の処理

PCollection<KV<String, String>> rows = someData 
    .apply(Combine.<String, String>perKey(new CombineUserIds())); 

public static class CombineUserIds implements SerializableFunction<Iterable<String>, String> { 
    private static final long serialVersionUID = 0; 

    @Override 
    public String apply(Iterable<String> userIdList) { 
    return Joiner.on(",").join(userIdList); 
    } 
} 


someDataは、そのキーGROUP_IDされた値であるUSER_ID PCollection<KV<String, String>>タイプです。
そして次は、全体のエラーメッセージにある
オラクルdocsから (b997767fac436e5c): java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:421) at java.lang.StringBuilder.append(StringBuilder.java:136) at java.lang.StringBuilder.append(StringBuilder.java:76) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:457) at java.lang.StringBuilder.append(StringBuilder.java:166) at java.lang.StringBuilder.append(StringBuilder.java:76) at com.google.common.base.Joiner.appendTo(Joiner.java:111) at com.google.common.base.Joiner.appendTo(Joiner.java:152) at com.google.common.base.Joiner.join(Joiner.java:193) at com.google.common.base.Joiner.join(Joiner.java:183) at com.moloco.dataflow.ml.adhoc.GenerateMLUserProfileSet$CombineUserIds.apply(GenerateMLUserProfileSet.java:189) at com.moloco.dataflow.ml.adhoc.GenerateMLUserProfileSet$CombineUserIds.apply(GenerateMLUserProfileSet.java:184) at com.google.cloud.dataflow.sdk.transforms.Combine$IterableCombineFn.mergeToSingleton(Combine.java:1613) at com.google.cloud.dataflow.sdk.transforms.Combine$IterableCombineFn.mergeAccumulators(Combine.java:1591) at com.google.cloud.dataflow.sdk.transforms.Combine$IterableCombineFn.mergeAccumulators(Combine.java:1536) at com.google.cloud.dataflow.sdk.transforms.Combine$CombineFn$2.mergeAccumulators(Combine.java:489) at com.google.cloud.dataflow.sdk.runners.worker.GroupAlsoByWindowsParDoFnFactory$MergingKeyedCombineFn.extractOutput(GroupAlsoByWindowsParDoFnFactory.java:249) at com.google.cloud.dataflow.sdk.runners.worker.GroupAlsoByWindowsParDoFnFactory$MergingKeyedCombineFn.extractOutput(GroupAlsoByWindowsParDoFnFactory.java:216) at com.google.cloud.dataflow.sdk.util.GroupAlsoByWindowsAndCombineDoFn$KeyedCombineFnRunner.extractOutput(GroupAlsoByWindowsAndCombineDoFn.java:243) at com.google.cloud.dataflow.sdk.util.GroupAlsoByWindowsAndCombineDoFn.closeWindow(GroupAlsoByWindowsAndCombineDoFn.java:206) at com.google.cloud.dataflow.sdk.util.GroupAlsoByWindowsAndCombineDoFn.processElement(GroupAlsoByWindowsAndCombineDoFn.java:192) at com.google.cloud.dataflow.sdk.util.SimpleDoFnRunner.invokeProcessElement(SimpleDoFnRunner.java:49) at com.google.cloud.dataflow.sdk.util.DoFnRunnerBase.processElement(DoFnRunnerBase.java:138) at com.google.cloud.dataflow.sdk.runners.worker.SimpleParDoFn.processElement(SimpleParDoFn.java:190) at com.google.cloud.dataflow.sdk.runners.worker.ForwardingParDoFn.processElement(ForwardingParDoFn.java:42) at com.google.cloud.dataflow.sdk.runners.worker.DataflowWorkerLoggingParDoFn.processElement(DataflowWorkerLoggingParDoFn.java:47) at com.google.cloud.dataflow.sdk.util.common.worker.ParDoOperation.process(ParDoOperation.java:53) at com.google.cloud.dataflow.sdk.util.common.worker.OutputReceiver.process(OutputReceiver.java:52) at com.google.cloud.dataflow.sdk.util.common.worker.ReadOperation.runReadLoop(ReadOperation.java:226)

+0

あなたはローカルでパイプラインを実行している、またはGoogleのクラウドにしていますか? –

+0

こんにちは@polleyg、私はGoogleの雲で実行されています。そして、私もn1-himem-32ワークタイプで試しました。しかし、メモリ不足の例外で失敗しました。 –

答えて

-2

、スレッドthread_nameで

例外:java.lang.OutOfMemoryErrorを:Javaヒープスペース

Cause: The detail message Java heap space indicates object could not be allocated in the Java heap. This error does not necessarily imply a memory leak. The problem can be as simple as a configuration issue, where the specified heap size (or the default size, if it is not specified) is insufficient for the application.

解決法1:以下のようにJVMヒープサイズを増やしてください。あなたは、あなたのプロジェクトが続いて

を望んでどのくらいのヒープスペースプロジェクトごとに指定することができ

は、Eclipse用です:

Run As - Run Configuration - Arguments - Vm Arguments, 

右マウスクリックは、この

-Xmx1024 

を追加しますまたは

-Xmx2048m 

対処方法2は(のみの後ソリューション1を試してみました):オラクルdocs

から再び

3.4.3 Monitor the Objects Pending Finalization When the OutOfMemoryError exception is thrown with the "Java heap space" > detail message, the cause can be excessive use of finalizers. To diagnose this, you have several options for monitoring the number of objects that are pending finalization:

The JConsole management tool can be used to monitor the number of objects that are pending finalization. This tool reports the pending finalization count in the memory statistics on the Summary tab pane. The count is approximate, but it can be used to characterize an application and understand if it relies a lot on finalization.

On Oracle Solaris and Linux operating systems, the jmap utility can be used with the -finalizerinfo option to print information about objects awaiting finalization.

An application can report the approximate number of objects pending finalization using the getObjectPendingFinalizationCount method of the java.lang.management.MemoryMXBean class. Links to the API documentation and example code can be found in Custom Diagnostic Tools . The example code can easily be extended to include the reporting of the pending finalization count.

+0

@Sundararaj Govindasamyありがとうございました。しかし、私はデータフロージョブを実行するためにeclipseを使用していませんし、各行のメモリはあなたが提案したメモリを超えるかもしれません。私は私の質問の解決策は、javaよりもむしろデータフロー自体に関連しているべきだと思います。とにかくありがとうございました。 –

+0

@Kuntae、あなたがeclipseを使用しているかどうかにかかわらず、根本的な問題はJava関連のみです。 userIdListのサイズは?参加するUserIdListsの数はいくつですか?このジョイナ全体で合計オブジェクトの合計は何ですか?たとえば、このジョイナ全体が10000個のオブジェクトに結合しようとしている場合、10000個のオブジェクトをJavaヒープに保持しようとしていますが、それらを保持するためのメモリがありません。あなたはJavaヒープに多くのメモリを割り当てる必要があります。または、オブジェクトが参照を持たないときにメモリからオブジェクトを消去するなど、メモリを効果的に使用しているコードを記述することができます。 –

+0

こんにちは@Sundararaj Govindasamy、 -Xmxフラグを使用してヒープサイズを設定することはできません([here](http:// stackoverflowを参照してください)。shufflerに悪影響を与えるのを避けるために、/ com/questions/30795924/cloud-dataflow-increase-jvm-xmx-value)私の場合、各行のサイズは大きすぎてメモリにロードできません。 (20億のユーザーIDと各ユーザーIDのサイズは約40〜50バイトです) –