[英]Spark join *without* shuffle
我正在嘗試優化我的Spark應用程序工作。
我試圖理解以下問題的要點: 在唯一鍵上連接DataFrame時如何避免隨機播放?
我已確保必須進行聯接操作的鍵分布在同一分區內(使用我的自定義分區程序)。
我也無法進行廣播加入,因為根據情況我的數據可能很大。
在上述問題的答案中,重新分區僅優化了聯接,但我需要的是聯接而沒有任何准備。 在分區內的鍵的幫助下進行聯接操作我就很好了。
可能嗎? 如果不存在類似的功能,我想實現類似joinperpartition的功能。
重新分區只會優化聯接,但我需要的是聯接而無需額外費用
這不是真的。 分區不僅可以“優化”聯接。 重新分區結合一個Partitioner
到您的RDD,這是一個地圖方聯接的關鍵組件。
我已確保必須進行聯接操作的鍵分布在同一分區中
Spark必須對此有所了解。 使用適當的API構建您的DataFrame,以使它們具有相同的Partitioner
,而spark將負責其余的工作。
只是以前的好答案的補充。 如果您在整個pyspark應用程序中多次加入一個大數據框,則將該表另存為存儲桶表,並在pyspark中將它們讀回為數據框。 這樣,您就可以避免在連接過程中多次混洗,因為數據已經被預先混洗和排序了。
因此,當Spark在兩個大型數據幀上選擇排序合並聯接時,它將在聯接操作期間跳過排序和混洗階段。 (您可以在spark UI中查看Wholecodegen來確認它)
df_data_1.coalesce(1).write.format('orc').bucketBy(20, 'joincolumn').sortBy("sortcolumn").mode("overwrite").saveAsTable('bucketed_table1')
df_data_2.coalesce(1).write.format('orc').bucketBy(20, 'joincolumn').sortBy("sortcolumn").mode("overwrite").saveAsTable('bucketed_table2')
df_bucket_table_1 = spark.table("bucketed_table1");
df_bucket_table_2 = spark.table("bucketed_table2");
spark.conf.set("spark.sql.autoBroadcastJoinThreshold", -1)
spark.conf.set("spark.sql.join.preferSortMergeJoin","true")
#creating alias for the dataframes:
from pyspark.sql.functions import *
df1 = df_bucket_table_1.alias('df1')
df2 = df_bucket_table_2.alias('df2')
DfInnerJoin = df1.join(df2, df1.joincolumn == df2.joincolumn,'inner').select('df1.*')
上面的聯接將沒有改組,但這僅在您必須在整個應用程序中多次聯接同一數據幀時才有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.