簡體   English   中英

多對多加入 Spark 中的大型數據集

[英]Many to many join on large datasets in Spark

我有兩個大型數據集 A 和 B,我希望在鍵 K 上加入它們。

每個數據集包含許多具有相同 K 值的行,因此這是一個多對多連接。

如果我只是天真地嘗試,此連接會因內存相關錯誤而失敗。

假設按 K 對兩個數據集進行分組,進行連接,然后使用一些技巧將其分解以獲得正確的結果不是一個可行的選擇,同樣是由於內存問題

人們是否發現了任何可以提高這種工作機會的聰明技巧?


更新:

添加一個非常非常人為的具體示例:

spark-shell --master local[4] --driver-memory 5G --conf spark.sql.autoBroadcastJoinThreshold=-1 --conf spark.sql.autoBroadcastJoinThreshold=-1 --conf spark.sql.shuffle.partitions=10000 --conf spark.default.parallelism=10000

val numbersA = (1 to 100000).toList.toDS
val numbersWithDataA = numbersA.repartition(10000).map(n => (n, 1, Array.fill[Byte](1000*1000)(0)))
numbersWithDataA.write.mode("overwrite").parquet("numbersWithDataA.parquet")

val numbersB = (1 to 100).toList.toDS
val numbersWithDataB = numbersB.repartition(100).map(n => (n, 1, Array.fill[Byte](1000*1000)(0)))
numbersWithDataB.write.mode("overwrite").parquet("numbersWithDataB.parquet")


val numbersWithDataInA = spark.read.parquet("numbersWithDataA.parquet").toDF("numberA", "one", "dataA")
val numbersWithDataInB = spark.read.parquet("numbersWithDataB.parquet").toDF("numberB", "one", "dataB")

numbersWithDataInA.join(numbersWithDataInB, Seq("one")).write.mode("overwrite").parquet("joined.parquet")

失敗Caused by: java.lang.OutOfMemoryError: Java heap space

--conf spark.sql.autoBroadcastJoinThreshold=-1

意味着您正在禁用廣播功能。

您可以將其更改為任何合適的 <2gb 值(因為存在 2gb 限制)。 spark.sql.autoBroadcastJoinThreshold根據spark 文檔默認為 10mb。 我不知道你禁用它的原因。 如果您取消它, SparkStregies會將路徑切換為 sortmerge join 或 shuffle hash join。 詳情請看我的文章

剩下的我認為沒有必要改變它加入 2 個數據集的常見模式。

進一步閱讀DataFrame join optimization - Broadcast Hash Join

更新:或者在你的真實例子中(不是做作:-))你可以做這些步驟

腳步 :

1)每個數據集找出連接鍵(例如,可以選擇唯一/不同的類別或國家或州字段)並將它們作為數組收集,因為您可以收集它的小數據。

2)對於數組中的每個類別元素,將 2 個數據集(使用小數據集連接)與類別作為條件添加到數據幀序列中。

3)減少和聯合這些數據幀。 標量示例:

val dfCatgories = Seq(df1Category1, df2Category2, df3Category3)
dfCatgories.reduce(_ union _)

注意:對於每次加入,我仍然更喜歡 BHJ,因為它會更少/沒有洗牌

暫無
暫無

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

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