为什么Spark使用java.lang.OutOfMemoryError失败:超出了GC开销限制?

我试图实现一个Hadoop Map / Reduce作业,在Spark之前工作正常。 Spark应用程序定义如下:

val data = spark.textFile(file, 2).cache() val result = data .map(//some pre-processing) .map(docWeightPar => (docWeightPar(0),docWeightPar(1)))) .flatMap(line => MyFunctions.combine(line)) .reduceByKey( _ + _) 

MyFunctions.combine在哪里

 def combine(tuples: Array[(String, String)]): IndexedSeq[(String,Double)] = for (i <- 0 to tuples.length - 2; j <- 1 to tuples.length - 1 ) yield (toKey(tuples(i)._1,tuples(j)._1),tuples(i)._2.toDouble * tuples(j)._2.toDouble) 

如果用于input的列表很大,并且这是引发exception的位置,则combine函数会生成大量映射键。

在Hadoop Map Reduce设置中,我没有问题,因为这是combine函数产生的点,Hadoop将地图对写入磁盘。 Spark似乎将所有内存都保留在内存中,直到爆炸出现java.lang.OutOfMemoryError: GC overhead limit exceeded

我可能做了一些非常基本的错误,但是我找不到任何关于如何从这个方面前进的指针,我想知道我该如何避免这种情况。 由于我是Scala和Spark的总Noob,我不确定问题是来自一个还是来自另一个,或者两者兼而有之。 我目前正在试图在我自己的笔记本电脑上运行这个程序,它适用于tuples组长度不是很长的input。 提前致谢。

调整记忆可能是一个很好的方法,正如已经提出的那样,因为这是一个昂贵的操作,以不利的方式缩放。 但也许一些代码更改将有所帮助。

你可以采取一种不同的方法在你的组合函数中,通过使用组合函数来避免if语句。 在组合操作之前,我还要将元组的第二个元素转换为双精度:

 tuples. // Convert to doubles only once map{ x=> (x._1, x._2.toDouble) }. // Take all pairwise combinations. Though this function // will not give self-pairs, which it looks like you might need combinations(2). // Your operation map{ x=> (toKey(x{0}._1, x{1}._1), x{0}._2*x{1}._2) } 

这将提供一个迭代器,您可以使用下游或,如果你想,转换为列表(或东西) toList

在启动spark-shellspark-submit时添加以下JVM参数:

 -Dspark.executor.memory=6g 

您也可以考虑在创buildSparkContext的实例时显式设置工作者的数量:

分布式集群

conf/slaves设置从站名称:

 val sc = new SparkContext("master", "MyApp") 

在文档( http://spark.apache.org/docs/latest/running-on-yarn.html )中,您可以阅读如何configuration执行程序和内存限制。 例如:

 --master yarn-cluster --num-executors 10 --executor-cores 3 --executor-memory 4g --driver-memory 5g --conf spark.yarn.executor.memoryOverhead=409 

memoryOverhead应该是执行程序内存的10%。

编辑:固定4096至409(下面的评论是指这个)

当我将spark.memory.fraction增加到大于0.6的值时,此JVM垃圾回收错误在我的情况下可重复发生。 所以最好将值保留为默认值以避免JVM垃圾收集错误。 这也推荐https://forums.databricks.com/questions/2202/javalangoutofmemoryerror-gc-overhead-limit-exceede.html

有关更多信息,请参阅为什么0.6spark.memory.fraction的最佳值,请参阅https://issues.apache.org/jira/browse/SPARK-15796