2015-11-20 23 views
6

我有一個DataFrame,我需要根據特定的分區寫入S3。代碼如下所示:如何控制使用分區時生成的地板文件的數量BY

dataframe 
    .write 
    .mode(SaveMode.Append) 
    .partitionBy("year", "month", "date", "country", "predicate") 
    .parquet(outputPath) 

partitionBy將數據分割成與數據在每個只是一點點(〜1GB)相當大數量的文件夾(〜400)。問題來了 - 因爲spark.sql.shuffle.partitions的默認值是200,每個文件夾中的1GB數據被分成200個小的parquet文件,總共寫入大約80000個parquet文件。由於多種原因,這不是最佳選擇,我想避免這種情況。

我當然可以將spark.sql.shuffle.partitions設置爲一個更小的數字,比如10,但據我所知,這個設置還控制了連接和聚合中洗牌的分區數量,所以我不想改變它。

有誰知道是否有另一種方法來控制有多少文件被寫入?

+1

您有沒有嘗試在'.write'之前對數據框進行重新分區?乍看起來似乎'spark.sql.shuffle.partitions'只用於混洗和連接,而不是其他地方。否則,你應該在partitionBy中打開一個額外的'numParameter'參數的票據。 –

+0

@MariusSoutier嗯......我認爲調用'repartition' _before_'write'會導致我的原始'dataframe'在被'partitionBy'函數重新分區之前被重新分區。將原始數據框重新分區爲10個分區肯定會導致OOM異常。但是,我剛開始測試它的工作。一旦完成,我會盡快回復。 –

+0

@MariusSoutier它的工作原理!太棒了。謝謝!您是否想將其作爲回覆發佈 - 然後我會將其標記爲回覆:-) –

回答

6

正如您指出的那樣,spark.sql.shuffle.partitions僅適用於SparkSQL中的洗牌和連接。

DataFrameWriterpartitionBy操作簡單上一分區數目(你DateFrameDateFrameWriter只要您撥打write移動 )。 (作者的分區只是將列分配給將要寫出的表/分區文件,所以它與分區數無關。這有點令人困惑。)

長話短說,只需重新分區DataFrame然後將其轉換爲作者。

相關問題