Python Pyspark java.lang.OutOfMemoryError:请求的数组大小超过VM限制

Python Pyspark java.lang.OutOfMemoryError:请求的数组大小超过VM限制,python,scala,hadoop,apache-spark,pyspark,Python,Scala,Hadoop,Apache Spark,Pyspark,我正在运行Pypark作业: spark-submit --master yarn-client --driver-memory 150G --num-executors 8 --executor-cores 4 --executor-memory 150G benchmark_script_1.py hdfs:///tmp/data/sample150k 128 hdfs:///tmp/output/sample150k | tee ~/output/sample150k.log 这项工作本

我正在运行Pypark作业:

spark-submit --master yarn-client --driver-memory 150G --num-executors 8 --executor-cores 4 --executor-memory 150G benchmark_script_1.py hdfs:///tmp/data/sample150k 128 hdfs:///tmp/output/sample150k | tee ~/output/sample150k.log
这项工作本身相当标准。它只是抓取一些文件并计数

print(str(datetime.now()) + " - Ingesting files...")
files = sc.wholeTextFiles(inputFileDir, partitions)
fileCount = files.count()
print(str(datetime.now()) + " - " + str(fileCount) + " files ingested")
源文件夹包含约150000个文件。不带复制的大约是35G,带复制的大约是105G。相当重但不疯狂

运行上述命令将提供以下堆栈跟踪:

15/08/11 15:39:20 WARN TaskSetManager: Lost task 61.3 in stage 0.0 (TID 76, <NODE>): java.io.IOException: Filesystem closed
        at org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:794)
        at org.apache.hadoop.hdfs.DFSInputStream.readWithStrategy(DFSInputStream.java:833)
        at org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:897)
        at java.io.DataInputStream.read(DataInputStream.java:100)
        at org.spark-project.guava.io.ByteStreams.copy(ByteStreams.java:207)
        at org.spark-project.guava.io.ByteStreams.toByteArray(ByteStreams.java:252)
        at org.apache.spark.input.WholeTextFileRecordReader.nextKeyValue(WholeTextFileRecordReader.scala:83)
        at org.apache.hadoop.mapreduce.lib.input.CombineFileRecordReader.nextKeyValue(CombineFileRecordReader.java:69)
        at org.apache.spark.rdd.NewHadoopRDD$$anon$1.hasNext(NewHadoopRDD.scala:143)
        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:39)
        at scala.collection.Iterator$class.foreach(Iterator.scala:727)
        at org.apache.spark.InterruptibleIterator.foreach(InterruptibleIterator.scala:28)
        at org.apache.spark.api.python.PythonRDD$.writeIteratorToStream(PythonRDD.scala:405)
        at org.apache.spark.api.python.PythonRDD$WriterThread$$anonfun$run$1.apply(PythonRDD.scala:243)
        at org.apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1617)
        at org.apache.spark.api.python.PythonRDD$WriterThread.run(PythonRDD.scala:205)
我已禁用HDFS缓存:

conf.set("fs.hdfs.impl.disable.cache", True)
请注意,Scala中完全相同的脚本根本没有任何问题

虽然这是一个很大的作业,但它有大量的内存可用。有人知道问题是什么吗

更新

为JVM分配了更多内存

export set JAVA_OPTS="-Xmx6G -XX:MaxPermSize=2G -XX:+UseCompressedOops"

遗憾的是,没有任何改进。

我在spark submit和Java上遇到了类似的问题,节省了8GB的数据帧。Docker容器,16芯,300GB内存。我还没有解决这个问题,但我遇到了几个可能的解决方法:

从第77页开始,建议这是shell的一个问题,在对象中使用@transient或封装可能是一种解决方法。这两种情况似乎都不适用

建议增加
spark.sql.shuffle.partitions
可能会有所帮助。他们建议将默认值“200”更改为“400”。我在spark defaults.conf中尝试了'800'和'2000',但仍然得到了OOM错误

还建议在代码中调用
DataFrame.repartition(400)
。或者,增加
分区的数量
作为调用
sc.wholeTextFiles(inputFileDir,partitions)的最后一个参数

如果堆大小大于32GB,则来自的
JAVA\u OPTS
建议将不适用,因为
-XX:+UseCompressedOops
已禁用(在JAVA 8中)

编辑

还尝试:

  • spark.default.parallelism=1000
    (默认值为内核数)。仍然是错误
  • dataFrame.repartition(1000)
    在代码中。仍然是错误
可能的解决办法

  • 使用intermediate
    RDD
    允许我创建数据帧,但是Spark反射模式不适用于MLLib(缺少numclass属性)

    DataFrame df=sqlContext.createDataFrame(sc.parallelize(List),LabeledPoint.class)

  • 通过使用中间JSON文件,我可以创建数据框架来使用MLLib

    saveAsJson(列表/*生成的数据*/,文件名);
    DataFrame df=sqlContext.read().json(文件名)


您是否尝试过增加火花、纱线、执行器、记忆头?
export set JAVA_OPTS="-Xmx6G -XX:MaxPermSize=2G -XX:+UseCompressedOops"