Apache Beam - GroupbyKeyOnly方法导致OutofMemory异常

时间:2017-12-16 03:53:52

标签: apache-spark apache-beam

我们正在使用在Spark runner上执行的Apache Beam。我们的案例如下。这两个用例都会导致OutofMemory错误。

1)加入 - 使用Apache Beam的2个大表 - 一个大小为120GB的表,另一个为60GB。当在GroupCombineFunctions.java内部调用groupByKeyOnly()时,这会导致OutofMemory错误。

2)GroupByKey - 我们基于如下的键对数据集进行分组。 PCollection>> costBasisRecords = masterDataResult.apply(GroupByKey.create());

此GroupbyKey操作也会导致OutOfmemory错误。

请您给我们一些建议,以便我们取得成果。

在线,我们看到 reduceByKey 方法 - 您能否指导我们如何为Spark跑步者实现该功能。

错误讯息:

java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.reflect.Array.newInstance(Array.java:75)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1897)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1529)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:76)
at org.apache.spark.serializer.DeserializationStream.readValue(Serializer.scala:171)
at org.apache.spark.serializer.DeserializationStream$$anon$2.getNext(Serializer.scala:201)
at org.apache.spark.serializer.DeserializationStream$$anon$2.getNext(Serializer.scala:198)
at org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)
at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)
at org.apache.spark.util.CompletionIterator.hasNext(CompletionIterator.scala:32)
at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:39)
at org.apache.spark.util.collection.ExternalAppendOnlyMap.insertAll(ExternalAppendOnlyMap.scala:152)
at org.apache.spark.Aggregator.combineValuesByKey(Aggregator.scala:45)
at org.apache.spark.shuffle.BlockStoreShuffleReader.read(BlockStoreShuffleReader.scala:89)
at org.apache.spark.rdd.ShuffledRDD.compute(ShuffledRDD.scala:98)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:270)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:270)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:270)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:270)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)
at org.apache.spark.rdd.RDD.iterator(RDD.scala:270)
at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)

2 个答案:

答案 0 :(得分:0)

Spark中的

reduceByKey与Apache Beam中的Combine.perKey类似,请参阅Programming Guide示例。

请注意,reduceByKeyCombine.perKey只有在每个密钥减少时才有效,否则您只会遇到相同的内存不足问题。例如,将每个键的所有整数组合到一个列表中不会减少内存使用量,但会对每个键的整数求和。

答案 1 :(得分:0)

如果可能,我肯定会建议使用Combine.perKey作为Lukasz建议。

如果您无法执行此操作或仍遇到OOM,请尝试通过增加分区数来减小分区大小。您可以通过手动设置spark.default.parallelism配置来增加shuffle分区的数量。这是explicitly used来确定groupByKeyOnly shuffle的分区方案。

通过手动构建的SparkContextOptions看起来探测配置的方式。有一个test case,显示了如何执行此操作。请注意,这需要您的管道程序直接链接到Spark。例如:

SparkConf conf = new SparkConf().set("spark.default.parallelism", parallelism);
JavaSparkContext jsc = new JavaSparkContext(conf);
SparkContextOptions options = PipelineOptionsFactory.as(SparkContextOptions.class);
options.setUsesProvidedSparkContext(true);
options.setProvidedSparkContext(jsc);
Pipeline p = Pipeline.create(options);
// ...

注意:Spark有自己的限制,即给定键的所有分组值必须适合处理该键的机器的内存。如果这不适用于您的数据集(即,您有非常强的密钥偏斜),那么您需要来组合而不是按组分组。

相关问题