簡體   English   中英

僅使用 Spark-SQL API 時廣播變量的使用

[英]Usage of Broadcast Variables when using only Spark-SQL API

在使用 Spark-RDD API 時,我們可以使用廣播變量來優化 Spark 分發不可變狀態的方式。

1) 廣播變量如何在內部工作?

我的假設是:對於用於對數據集執行操作的每個閉包,所有它引用的變量都必須被序列化、通過網絡傳輸並與任務一起恢復,以便閉包可以被執行。

當注冊這樣的廣播變量時​​:

val broadcastVar = sc.broadcast("hello world")

返回的對象( Broadcast[String] )不保留對實際對象(“hello world”)的引用,而只保留一些 ID。 當一個廣播變量句柄從上面所說的閉包中被引用時,它將像其他所有變量一樣被序列化 - 只是廣播變量句柄本身不包含實際對象。

當閉包稍后在目標節點上執行時,實際對象(“hello world”)已經轉移到每個節點。 當閉包到達調用broadcastVar.value的點時, broadcastVar.value變量句柄在內部使用 ID 檢索實際對象。

這個假設正確嗎?

2) 有沒有辦法在 Spark-SQL 中利用這種機制?

假設我有一組允許的值。

使用 RDD-API 時,我將為我的 allowedValues 創建一個廣播變量:

val broadcastAllowedValues = sc.broadcast(allowedValues) // Broadcast[Set[String]]

rdd.filter(row => broadcastAllowedValues.value.contains(row("mycol")))

當然,當使用 Spark-SQL-API 時,我會使用Column.isin / Column.isInCollection方法:

dataframe.where(col("mycol").isInCollection(allowedValues))

但似乎我無法通過這種方式獲得廣播變量的優勢。

另外,如果我將這段代碼更改為以下內容:

val broadcastAllowedValues = sc.broadcast(allowedValues) // Broadcast[Set[String]]

dataframe.where(col("mycol").isInCollection(allowedValues.value))

這部分:

col("mycol").isInCollection(allowedValues.value)
// and more important this part:
allowedValues.value

將已經在驅動程序上進行評估,從而產生一個新的Column -Object。 所以廣播變量在這里失去了它的優勢。 與第一個示例相比,它甚至會有一些開銷......

有沒有辦法使用 Spark-SQL-API 來利用廣播變量,或者我是否必須在這些點顯式使用 RDD-API?

廣播變量如何在內部工作?

廣播的數據被序列化並物理移動到所有執行器。 根據關於Broadcast Variables的文檔,它說

“廣播變量允許程序員在每台機器上緩存一個只讀變量,而不是隨任務一起傳送它的副本。”

有沒有辦法在 Spark-SQL 中利用這種機制?

是的,有一種方法可以利用優勢。 Spark 在加入大小數據幀時默認應用廣播哈希加入

根據“Learning Spark - 2nd edition”一書,它說:

“默認情況下,如果較小的數據集小於 10MB,Spark 將使用廣播連接。此配置在spark.sql.autoBroadcastJoinThreshold設置;您可以根據每個執行程序和在司機。”

你的情況,你需要列出所有獨特ALLOWEDVALUES成簡單的數據幀(數據幀稱為allowedeValuesDF )只有一列(列名為allowValues )和應用加入到過濾您的dataframe

像這樣的東西:

import org.apache.spark.sql.functions.broadcast
val result = dataframe.join(broadcast(allowedValuesDF), "mycol === allowedValues")

實際上,您可以省略broadcast因為默認情況下 Spark 會執行廣播連接。

編輯:

在更高版本的 Spark 中,您還可以在 SQL 語法中使用連接提示來告訴執行引擎使用哪些策略。 SQL 文檔中提供了詳細信息,下面提供了一個示例:

-- Join Hints for broadcast join 
SELECT /*+ BROADCAST(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;

暫無
暫無

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

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