[Spark內核] 第42課:Spark Broadcast內幕解密:Broadcast運行機制完全解密、Broadcast源碼解析、Broadcast最佳實踐

本課主題

  • Broadcast 運行原理圖
  • Broadcast 源碼解析

 

Broadcast 運行原理圖

Broadcast 就是將數據從一個節點發送到其餘的節點上; 例如 Driver 上有一張表,而 Executor 中的每一個並行執行的Task (100萬個Task) 都要查詢這張表的話,那咱們經過 Broadcast 的方式就只須要往每一個Executor 把這張表發送一次就好了,Executor 中的每一個運行的 Task 查詢這張惟一的表,而不是每次執行的時候都從 Driver 中得到這張表!apache

Broadcast 是分佈式的共享數據,默認狀況下只要程序在運行 Broadcast 變量就會存在,由於 Broadcast 在底層是經過 BlockManager 管理的,Broadcast 是在建立 SparkContext 時被建立的!你也能夠手動指定或者配置具體週期來銷燬 Broadcast 變量!Broadcast 通常用於處理共享配置文件,通用的數據子,經常使用的數據結構等等;可是不適合存放太大的數據在Broadcast。Broadcast 不會內存溢出,由於其數據的保存的 Storage Level 是 MEMORY_AND_DISK 的方式(首先優先放在內存中,若是內存不夠才放在磁盤上)雖然如此,咱們也不能夠放入太大的數據在 Broadcast 中,由於網絡 I/O 和可能的單點壓力會很是大!Broadcast 有兩種方式,HttpBroadcast 和 TorrentBroadcast。網絡

廣播 Broadcast 變量只是只讀變量,最爲輕鬆的保持數據的一致性!數據結構

Broadcast 的使用以下:分佈式

val broadcastVar = sc.broadcast(Array(1, 2, 3))
// broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]] = Broadcast(0)

broadcastVar.value
// res0: Array[Int] = Array(1, 2, 3)

[下圖是 Broadcast 的原理圖 - HttpBroadcast 的方式]性能

  • 沒有廣播的狀況:經過網絡傳輸把變量發送到每個 Task 中,會產生4個Number的數據副本,每一個副本都會佔用必定的內存空間,若是變量比較大,會致使則極易出現OOM。
  • 使用廣播的狀況:經過Broadcast把變量傳輸到Executor的內存中,Executor級別共享惟一的一份廣播變量,極大的減小網絡傳輸和內存消耗! ! !

 

BT 的方式是,假設你 A 節點用了這個數據,A 節點也會做爲一個數據來源或者是供應源,這個時候就有兩個節點能夠供應原數據,而後第三個節點用完以後也變成一個供應源,愈多節點用這副廣播數據,會愈多供應源。大數據

 

Broadcast 源碼解析

HttpBroadcast 方式的 Broadcastspa

  1. 最開始的時候數據放在 Driver 的本地文件系統中,Driver 在本地會建立一個文件夾來存放 Broadcast 中的 data,而後啓動 HttpServer 來訪問文件夾中的數據,同時寫入到BlockManager (Storage Level 是MEMORY_AND_DISK) 中得到 BlockId (BroadcastBlockId) ,當第一次 Executor 中的 Task 要訪問 Broadcast 變量的時候,會向 Driver 經過 HttpServer 來訪問數據, 而後會在 Executor 中的 Broadcast 中註冊該 Broadcast 中的數據,這樣後續須要的 Task 訪問的 Broadcast 的變量的時候會首先查詢BlockManager 中有沒有該數據,若是有就直接使用;
  2. BroadcastManager 是用來管理 Broadcast,該實例是在 SparkContext 建立 SparkEnv 的時候建立的。

    在實例化 BroadcastManager 的時候調用 initialized 方法,這個方法經過建立 BroadcastFactory 工廠類來構建具體的實際的 Broadcast 類型,默認是狀況下是 TorrentBroadcastFactory


  3. HttpBroadcast 存在單點故障,和網絡IO性能問題,因此默認使用 TorrentBroadcast 的方式,開始數據在 Driver 中,假設 A 節點用了數據,B 訪問的時候 A 節點就變成數據源,依次類推,都是數據源,你數據的節點愈多,你獲取數據的選擇性就愈多,這樣就不是致使一個節點壓力太大,也不會致使在特定的節點上網絡壓力太大,數據源越多,節點壓力會大大下降,固然是被 BlockManager 進行管理的。
  4. TorrentBroadcast 按照 Block_Size (默認是 4MB) 講 Broadcast 中的數據劃分爲不一樣的 Block

    而後將分塊信息也就是 meta 信息存放到 Driver 的 BlockManager 中,同時會告訴 BlockManagerMaster,此時就會變成全局信息說明 Meta 信息存放完畢。

在 SparkContext 中手動調用 broadcast 方法scala

 

 

總結

第一種就是 HttpBroadcast,在 Driver 中建立一個文件夾,搞一個 HttpServer,你須要的話 Executor 經過 Http 抓一份過來,放在 BlockManager 中,下一次再用的話就首先到 BlockManager 取,BlockManager 沒有再去 Driver 去取,因此這存在單點故障,和網絡IO性能問題。blog

第二種就是 TorrentBroadcast,首先是 Driver 中有,建立一個文件夾,它是向 BroadcastManagerMaster 註冊,而後 Executor 須要的話本身拿一份,拿一份的時候它要通知 BlockManagerMaster 就有另一份副本,後績 Executor 要拿副本就有多種選擇。圖片

 

 

參考資料 

資料來源來至 DT大數據夢工廠 大數據傳奇行動 第42課:Spark Broadcast內幕解密:Broadcast運行機制完全解密、Broadcast源碼解析、Broadcast最佳實踐

Spark源碼圖片取自於 Spark 1.6.0版本

相關文章
相關標籤/搜索