在写入和重新读取实木复合地板文件时保留数据帧分区

时间:2018-06-28 19:54:02

标签: apache-spark parquet

当我将具有已定义分区的数据帧作为拼写文件写入磁盘,然后再次重新读取拼写文件时,该分区会丢失。有没有办法在写入和重新读取期间保留数据帧的原始分区?

示例代码

//create a dataframe with 100 partitions and print the number of partitions
val originalDf = spark.sparkContext.parallelize(1 to 10000).toDF().repartition(100)
println("partitions before writing to disk: " + originalDf.rdd.partitions.length)

//write the dataframe to a parquet file and count the number of files actually written to disk
originalDf.write.mode(SaveMode.Overwrite).parquet("tmp/testds")
println("files written to disk: " + new File("tmp/testds").list.size)

//re-read the parquet file into a dataframe and print the number of partitions 
val readDf = spark.read.parquet("tmp/testds")
println("partitions after reading from disk: " + readDf.rdd.partitions.length)

打印出

partitions before writing to disk: 100
files written to disk: 202
partitions after reading from disk: 4

观察:

  • 第一个数字是预期结果,数据框包含100个分区
  • 第二个数字对我来说也不错:我得到100个*.parquet文件,100个*.parquet.crc文件和两个_SUCCESS文件,因此实木复合地板文件仍然由100个分区组成
  • 第三行显示,在再次读取实木复合地板文件后,原始分区丢失,并且读取实木复合地板文件后的分区数量发生了变化。分区数量与我的Spark集群的执行者数量有关
  • 无论将镶木文件写入本地磁盘还是Hdfs存储,结果都是相同的
  • readDf上执行操作时,我在SparkUI中看到创建了四个任务,在foreachPartition上调用readDf时,该函数执行了四次

是否有一种方法可以保留数据帧的原始分区,而无需在读取镶木文件后再次调用repartition(100)

背景:在我的实际应用程序中,我编写了许多具有精心调整的分区的不同数据集,并且我想还原这些分区,而不必为每个数据帧分别记录编写时分区的样子他们到磁盘上。

我正在使用Spark 2.3.0。

0 个答案:

没有答案