Spark java.lang.OutOfMemoryError:Java 堆空间[重复]

问题描述 投票:0回答:2

当我使用 Spark 运行模型训练管道时,出现上述错误

val inputData = spark.read
  .option("header", true)
  .option("mode","DROPMALFORMED")
  .csv(input)
  .repartition(500)
  .toDF("b", "c")
  .withColumn("b", lower(col("b")))
  .withColumn("c", lower(col("c")))
  .toDF("b", "c")
  .na.drop()

inputData 约有 2500 万行,大小约为 2GB。模型构建阶段是这样发生的

val tokenizer = new Tokenizer()
  .setInputCol("c")
  .setOutputCol("tokens")

val cvSpec = new CountVectorizer()
  .setInputCol("tokens")
  .setOutputCol("features")
  .setMinDF(minDF)
  .setVocabSize(vocabSize)

val nb = new NaiveBayes()
  .setLabelCol("bi")
  .setFeaturesCol("features")
  .setPredictionCol("prediction")
  .setSmoothing(smoothing)

new Pipeline().setStages(Array(tokenizer, cvSpec, nb)).fit(inputData)

我使用以下命令在具有 16GB RAM 的计算机上本地运行上述 Spark 作业

spark-submit  \
    --class holmes.model.building.ModelBuilder ./holmes-model-building/target/scala-2.11/holmes-model-building_2.11-1.0.0-SNAPSHOT-7d6978.jar   \
    --master local[*] \
    --conf spark.serializer=org.apache.spark.serializer.KryoSerializer \
    --conf spark.kryoserializer.buffer.max=2000m \
    --conf spark.driver.maxResultSize=2g \
    --conf spark.rpc.message.maxSize=1024 \
    --conf spark.memory.offHeap.enabled=true \
    --conf spark.memory.offHeap.size=50g \
    --driver-memory=12g

oom错误是由(在堆栈跟踪的底部)触发的 通过 org.apache.spark.util.collection.ExternalSorter.writePartitionedFile(ExternalSorter.scala:706)

日志:

Caused by: java.lang.OutOfMemoryError: Java heap space 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) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2027) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535) org.apache.spark.util.collection.ExternalSorter.writePartitionedFile(ExternalSorter.scala:706) 

任何建议都会很棒:)

apache-spark out-of-memory spark-submit
2个回答
4
投票

我会尝试的事情:

1) 删除

spark.memory.offHeap.enabled=true
并将驱动程序内存增加到盒子上可用内存的 90% 左右。您可能已经意识到这一点,因为您没有设置执行程序内存,但在本地模式下,驱动程序和执行程序都在由驱动程序内存控制的同一进程中运行。我还没有尝试过,但是
offHeap
功能听起来价值有限。 参考

2)实际集群而不是本地模式。更多的节点显然会给你更多的 RAM。

3a) 如果您想坚持使用本地模式,请尝试使用更少的内核。您可以通过指定主设置中要使用的核心数量来完成此操作,例如

--master local[4]
而不是使用所有核心的
local[*]
。使用较少的线程同时处理数据将导致在任何给定时间 RAM 中的数据较少。

3b) 如果您迁移到集群,出于与上述相同的原因,您可能还需要调整执行器核心的数量。您可以使用

--executor-cores
标志来执行此操作。

4) 尝试使用更多分区。在您的示例代码中,您重新分区为 500 个分区,也许尝试 1000 个或 2000 个?更多分区意味着每个分区更小,内存压力更小。


1
投票

通常,当Java堆中没有足够的空间来分配对象时,会抛出此错误。在这种情况下,垃圾收集器无法腾出空间来容纳新对象,并且堆也无法进一步扩展。此外,当本机内存不足以支持 Java 类的加载时,也可能会引发此错误。在极少数情况下,当花费过多时间进行垃圾收集并且释放很少内存时,可能会抛出 java.lang.OutOfMemoryError。

如何修复错误:

如何设置 Apache Spark Executor 内存

Spark java.lang.OutOfMemoryError:Java 堆空间

© www.soinside.com 2019 - 2024. All rights reserved.