簡體   English   中英

如何避免 pyspark 中的 join 操作過度洗牌?

[英]How to avoid excessive shuffles in join operation in pyspark?

我有一個大火花 dataframe,大小約為 25 GB,我必須與另一個大小約為 15 GB 的 dataframe 連接。

現在,當我運行代碼時,大約需要 15 分鍾才能完成

資源分配為 40 個執行程序,每個執行程序 128 GB memory

當我完成它的執行計划時,正在執行排序合並連接。

問題是:

連接在相同的鍵但不同的表上執行大約 5 到 6 次,因為在合並/連接執行的每個連接的數據之前,它花費了大部分時間對數據進行排序和共同定位分區。

那么有沒有辦法在執行連接之前對數據進行排序,以便不對每個連接執行排序操作或以這樣的方式進行優化,以減少排序時間和實際連接數據的更多時間?

我只想在執行連接之前對我的 dataframe 進行排序,但不知道該怎么做?

例如:

如果我的 dataframe 正在加入 id 列

joined_df = df1.join(df2,df1.id==df2.id)

如何在加入之前根據“id”對 dataframe 進行排序,以便分區位於同一位置?

那么有沒有辦法在執行連接之前對數據進行排序,以便不對每個連接執行排序操作或以這樣的方式進行優化,以減少排序時間和實際連接數據的更多時間?

聞起來像水桶。

是一種優化技術,它使用桶(和分桶列)來確定數據分區並避免數據混洗。

這個想法是對數據集進行bucketBy ,以便 Spark 知道鍵是位於同一位置的(已經預先洗牌)。 在參與連接的 DataFrame 中,桶的數量和桶列的數量必須相同。

請注意,Hive 或 Spark 表 ( saveAsTable ) 支持此功能,因為存儲桶元數據是從元存儲(Spark 或 Hive)獲取的。

過去,通過連接列對輸入數據幀進行重新分區,我取得了很好的結果。 雖然這並不能避免洗牌,但它確實使洗牌明確,允許您選擇專門用於連接的分區數量(而不是設置spark.sql.shuffle.partitions將適用於所有連接)。

如果您需要在多個作業中多次讀取數據集,而寫入持久存儲的成本得到回報,則分桶是一種有用的技術。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM