Spark開發-廣播變數

Xlucas發表於2017-10-01

核心
1、什麼是廣播變數
2、為什麼需要廣播變數
3、案例

什麼是廣播變數
Spark有兩種共享變數——累加器、廣播變數。廣播變數可以讓程式高效地向所有工作節點傳送一個較大的只讀值,以供一個或多個Spark操作使用。

為什麼需要廣播變數
Spark中分散式執行的程式碼需要傳遞到各個Executor的Task上執行。對於一些只讀、固定的資料(比如從DB中讀出的資料),每次都需要Driver廣播到各個Task上,這樣效率低下。廣播變數允許將變數只廣播(提前廣播)給各個Executor。該Executor上的各個Task再從所在節點的BlockManager獲取變數,而不是從Driver獲取變數,從而提升了效率。
一個Executor只需要在第一個Task啟動時,獲得一份Broadcast資料,之後的Task都從本節點的BlockManager中獲取相關資料。
使用方法
1.呼叫SparkContext.broadcast方法建立一個Broadcast[T]物件。任何序列化的型別都可以這麼實現。
2.通過value屬性訪問改物件的值(Java之中為value()方法)
3.變數只會被髮送到各個節點一次,應作為只讀值處理(修改這個值不會影響到別的節點)

案例
下面是一個wordCount的案例。程式碼可以檢視之前的文章

我們寫了一個這樣的類,這個類主要實現了v1+v2這一步
這裡寫圖片描述

廣播變數
這裡寫圖片描述

我們這裡通過wd.value()獲取廣播的例項,在通過例項呼叫方法,
這裡寫圖片描述

但是通過執行我們可以發現,這裡我們的程式出現了不能序列化的問題。

Exception in thread "main" java.io.NotSerializableException: com.xlucas.Words
Serialization stack:
    - object not serializable (class: com.xlucas.Words, value: com.xlucas.Words@23ba74fe)
    at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47)
    at org.apache.spark.broadcast.TorrentBroadcast$.blockifyObject(TorrentBroadcast.scala:203)
    at org.apache.spark.broadcast.TorrentBroadcast.writeBlocks(TorrentBroadcast.scala:102)
    at org.apache.spark.broadcast.TorrentBroadcast.<init>(TorrentBroadcast.scala:85)
    at org.apache.spark.broadcast.TorrentBroadcastFactory.newBroadcast(TorrentBroadcastFactory.scala:34)
    at org.apache.spark.broadcast.BroadcastManager.newBroadcast(BroadcastManager.scala:63)
    at org.apache.spark.SparkContext.broadcast(SparkContext.scala:1326)
    at org.apache.spark.api.java.JavaSparkContext.broadcast(JavaSparkContext.scala:639)
    at com.xlucas.WordCount.main(WordCount.java:38)

如果需要解決這個問題那麼應該怎麼做呢??
如果你的Words不能序列化,也不想去序列化,建議新建一個類,這個類繼承了Words這個類,在實現了序列化的介面
這裡寫圖片描述
這裡我們的廣播變數需要採用Word這個類了
這裡寫圖片描述

這樣執行就沒有問題了

相關文章