簡體   English   中英

Spark Join *無*洗牌

[英]Spark join *without* shuffle

我正在嘗試優化我的Spark應用程序工作。

我試圖理解以下問題的要點: 在唯一鍵上連接DataFrame時如何避免隨機播放?

  1. 我已確保必須進行聯接操作的鍵分布在同一分區內(使用我的自定義分區程序)。

  2. 我也無法進行廣播加入,因為根據情況我的數據可能很大。

  3. 在上述問題的答案中,重新分區僅優化了聯接,但我需要的是聯接而沒有任何准備。 在分區內的鍵的幫助下進行聯接操作我就很好了。

可能嗎? 如果不存在類似的功能,我想實現類似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.

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