Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Spark:读取和写入拼花导致OutOfMemoryError:Java堆空间_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala Spark:读取和写入拼花导致OutOfMemoryError:Java堆空间

Scala Spark:读取和写入拼花导致OutOfMemoryError:Java堆空间,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我编写了一些代码来读取拼花地板文件,稍微切换模式,然后将数据写入一个新的拼花地板文件。代码如下所示: ... val schema = StructType( List( StructField("id", LongType, false), StructField("data", ArrayType(FloatType), false) ) ) val data = sqlContext.read.parquet(file.getAbsolutePath) val r

我编写了一些代码来读取拼花地板文件,稍微切换模式,然后将数据写入一个新的拼花地板文件。代码如下所示:

...
val schema = StructType(
  List(
    StructField("id", LongType, false),
    StructField("data", ArrayType(FloatType), false)
  )
)

val data = sqlContext.read.parquet(file.getAbsolutePath)
val revisedData = data.map(r =>  Row(r.getInt(0).toLong, r.getSeq[Float](1)))
val df = sqlContext.createDataFrame(revisedData,  schema)

Writer.writeToParquet(df)
Writer

object Writer {
    def writeToParquet(df : DataFrame) : Unit = {
       val future = Future {
         df.write.mode(SaveMode.Append).save(path)
       }

       Await.ready(future, Duration.Inf)
    }
}
对于一个大约4GB的文件,我的程序中断,引发了一个OutOfMemoryError:Java堆空间。我为执行器设置了6GB的内存(使用
-Dspark.executor.memory=6g
),提高了JVM堆空间(使用
-Xmx6g
),将Kryo序列化程序缓冲区增加到2GB(使用
System.setProperty(“spark.kryoserializer.buffer.mb”,“2048”)
)。然而,我仍然得到了错误

这是堆栈跟踪:

java.lang.OutOfMemoryError: Java heap space
  at com.esotericsoftware.kryo.io.Output.<init>(Output.java:35)
  at org.apache.spark.serializer.KryoSerializer.newKryoOutput(KryoSerializer.scala:76)
  at org.apache.spark.serializer.KryoSerializerInstance.output$lzycompute(KryoSerializer.scala:243)
  at org.apache.spark.serializer.KryoSerializerInstance.output(KryoSerializer.scala:243)
  at org.apache.spark.serializer.KryoSerializerInstance.serialize(KryoSerializer.scala:247)
  at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:236)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:744)
java.lang.OutOfMemoryError:java堆空间
在com.esotericsoftware.kryo.io.Output.(Output.java:35)
位于org.apache.spark.serializer.KryoSerializer.newKryoOutput(KryoSerializer.scala:76)
在org.apache.spark.serializer.kryoserializerrinstance.output$lzycompute上(KryoSerializer.scala:243)
位于org.apache.spark.serializer.kryoserializerrinstance.output(KryoSerializer.scala:243)
位于org.apache.spark.serializer.KryoSerializerInstance.serialize(KryoSerializer.scala:247)
位于org.apache.spark.executor.executor$TaskRunner.run(executor.scala:236)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
运行(Thread.java:744)

如何避免此错误?

在我的评论之后,有两件事:

1) 您需要注意
spark.kryoserializer.buffer.mb
属性名称,在最新的spark中,他们将其更改为
spark.kryoserializer.buffer
spark.kryoserializer.buffer.max

2) 您必须注意缓冲区的大小和堆的大小,它必须足够大以存储您正在写入的单个记录,但不能太大,因为kryo正在创建一个该大小的显式
byte[]
(并且为2GB分配一个
byte
数组通常是个坏主意)。尝试使用适当的属性降低缓冲区大小。

使用SparkyR, 具有相同的OutOfMemoryError, 尽管减少了spark.kryoserializer.buffer, 无法阅读拼花地板一个我能写的文件, 我的解决办法是:

禁用“急切”:(内存=FALSE)

spark 2.3.0 第1.0.0节
R版本3.4.2

首先,您没有在任何地方使用
revisedData
。第二,你的房间到底在哪里?最后,文件的结构是什么(有多少列)?对不起,我已经纠正了代码中的错误。OOM是在
com.esotericsoftware.kryo.io.Output.(Output.java:35)
(请参阅更新后的带有堆栈跟踪的帖子)中提出的。原始文件有两列,即
Int
Seq[Float]
列您使用的Spark版本是什么?确保使用适当的kryoserializer缓冲区属性(1.4.1没有
mb
one)。我会尽量减少缓冲区大小,2GB太多了。但它需要足够大以容纳数据,所以请检查记录的长度,并尝试使用尽可能小的缓冲区。看起来spark版本使用的是kryo-2.22,它基本上尝试做
buffer=newbyte[bufferSize]但是没有那么多空间。是的,现在它可以工作了!我使用了旧版本Spark中的错误缓冲区属性。切换了属性,现在运行平稳。谢谢@naivge ok将其添加为一个答案
spark_read_parquet(sc,name=curName,file.path("file://",srcFile), header=true, memory=FALSE)