在spark中保存固定大小的镶木地板输出文件

时间:2018-04-13 23:14:41

标签: apache-spark spark-dataframe

我有160GB的数据,DATE列上的分区以及在spark 1.6.0上运行的镶木地板文件格式存储。 我需要在每个分区中存储具有相同大小的文件的输出镶木地板文件,其固定大小比如每个100MB。

我尝试使用以下代码:

  val blockSize= 1024*1024*100
  sc.hadoopConfiguration.setInt("dfs.blocksize", blockSize)
  sc.hadoopConfiguration.setInt("parquet.block.size",blockSize)

df1.write.partitionBy( “DATE”)。镶木地板( “output_file_path”)

以上配置不起作用,它创建了多个默认分区数的文件,而不是100 MB文件。

2 个答案:

答案 0 :(得分:0)

您可以尝试以下方法:

首先,您应该估算数据中单行的大小 它很难准确(因为镶木地板文件也包含元数据),但你可以获取1000行数据,写入文件,并估计单行的大小

从中计算出100MB中的行数:

N = 100MB / size_of_row 

现在您可以创建一个附加列,每行包含一个桶ID:

val df2 = df.withColumn("bucket", (rank.over(Window.partitionBy("DATE")) / N).cast(IntegerType))

现在您可以按日期和存储桶重新分区数据:

df2
  .repartition($"DATE", $"bucket")
  .dropColumn("bucket")
  .write
  .parquet(...)

答案 1 :(得分:0)

不可能为每个文件获得完全相同的大小,但是你可以给Spark提供足够的提示,使它们“在”某个大小之内。 一般目标是使每个文件等于HDFS块大小,并且每个文件包含一个(或多个)行组。您希望行组适合一个HDFS块。如果行组不适合一个块,则需要进行额外的网络调用以读取另一个HDFS块以完全读取行组。

要实现此目的,请执行以下操作:

  • 将spark conf中的spark.sql.files.maxPartitionBytes设置为256 MB(等于您的HDFS块 大小)
  • 将Spark中的镶木地板编写器选项上的parquet.block.size设置为256 MB。

729edd5