我有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文件。
答案 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块以完全读取行组。
要实现此目的,请执行以下操作:
729edd5