I have a DataFrame that I need to write to S3 according to a specific partitioning. The code looks like this:
dataframe
.write
.mode(SaveMode.Append)
.partitionBy("year", "month", "date", "country", "predicate")
.parquet(outputPath)
The partitionBy split the data into a fairly large number of folders (~400) with just a little bit of data (~1GB) in each. And here comes the problem - because the default value of spark.sql.shuffle.partitions is 200, the 1GB of data in each folder is split into 200 small parquet files, resulting in roughly 80000 parquet files being written in total. This is not optimal for a number of reasons and I would like to avoid this.
I can of course set the spark.sql.shuffle.partitions to a much smaller number, say 10, but as I understand this setting also controls the number of partitions for shuffles in joins and aggregation, so I don't really want to change this.
Does anyone know if there is another way to control how many files are written?
As you noted correctly, spark.sql.shuffle.partitions only applies to shuffles and joins in SparkSQL.
partitionBy in DataFrameWriter (you move
from DataFrame to DataFrameWriter as soon as you call write) simply operates on the previous number of partitions. (The writer's partitionBy only assigns columns to the table / parquet file that will be written out, so it has nothing to do with the number of partitions. This is a bit confusing.)
Long story short, just repartition the DataFrame before you transform it to a writer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With