Parquet在阅读

时间:2015-12-06 06:02:54

标签: apache-spark mapreduce bigdata parquet

我正在尝试与以镶木地板格式存储的大矩阵相乘,所以小心不要将RDD存储在内存中,但是从镶木地板阅读器中收到OOM错误:

15/12/06 05:23:36 WARN TaskSetManager: Lost task 950.0 in stage 4.0   
(TID 28398, 172.31.34.233): java.lang.OutOfMemoryError: Java heap space
at org.apache.parquet.hadoop.ParquetFileReader$ConsecutiveChunkList.readAll(ParquetFileReader.java:755)
at org.apache.parquet.hadoop.ParquetFileReader.readNextRowGroup(ParquetFileReader.java:494)
at org.apache.parquet.hadoop.InternalParquetRecordReader.checkRead(InternalParquetRecordReader.java:127)
at org.apache.parquet.hadoop.InternalParquetRecordReader.nextKeyValue(InternalParquetRecordReader.java:208)
at org.apache.parquet.hadoop.ParquetRecordReader.nextKeyValue(ParquetRecordReader.java:201)
...

具体来说,矩阵是一个46752×54843120的32位浮点密集矩阵,以镶木地板格式存储(每行约1.7GB未压缩)。

以下代码将此矩阵作为Spark IndexedRowMatrix加载并将其乘以随机向量(行与关联的字符串标签一起存储,并且浮点数必须转换为双精度数,因为IndexedRows只能使用双精度数):

val rows = {
  sqlContext.read.parquet(datafname).rdd.map {
    case SQLRow(rowname: String, values: WrappedArray[Float]) =>
    // DenseVectors have to be doubles
      val vector = new DenseVector(values.toArray.map(v => v.toDouble)) 
      new IndexedRow(indexLUT(rowname), vector)
    }
}

val nrows : Long = 46752
val ncols = 54843120
val A = new IndexedRowMatrix(rows, nrows, ncols)
A.rows.unpersist() // doesn't help avoid OOM

val x = new DenseMatrix(ncols, 1, BDV.rand(ncols).data)
A.multiply(x).rows.collect

我在运行

时使用以下选项
--driver-memory 220G
--num-executors 203
--executor-cores 4
--executor-memory 25G
--conf spark.storage.memoryFraction=0

镶木地板文件有25573个分区,因此每个分区的未压缩Float值应小于4Gb;我希望这应该意味着当前执行程序内存远远不够(我无法提升执行程序内存设置)。

任何想法为什么会遇到OOM错误以及如何修复它?据我所知,镶木地板读卡器没有理由存放任何东西。

0 个答案:

没有答案