Spark 核心元件解析

2022-07-16 04:24:08 字數 4489 閱讀 2970

blockmanager 是整個 spark 底層負責資料儲存與管理的乙個元件,driver 和

executor 的所有資料都由對應的 blockmanager 進行管理。

driver 上有 blockmanagermaster,負責對各個節點上的 blockmanager 內部管理

的資料的元資料進行維護,比如 block 的增刪改等操作,都會在這裡維護好元資料

的變更。

每個節點都有乙個 blockmanager,每個 blockmanager 建立之後,第一件事即

使去向 blockmanagermaster 進行註冊,此時 blockmanagermaster 會為其長難句對應

的 blockmanagerinfo。

blockmanager 執行原理如下圖所示:

blockmanagermaster 與 blockmanager 的關係非常像 namenode 與 datanode 的

關係,blockmanagermaster 中儲存中 blockmanager 內部管理資料的元資料,進行維

護,當 blockmanager 進行 block 增刪改等操作時,都會在 blockmanagermaster 中進

行元資料的變更,這與 namenode 維護 datanode 的元資料資訊,datanode 中資料

發生變化時 namenode 中的元資料資訊也會相應變化是一致的。

每個節點上都有乙個 blockmanager,blockmanager 中有 3 個非常重要的元件:

· diskstore:負責對磁碟資料進行讀寫;

· memorystore:負責對記憶體資料進行讀寫;

· blocktransferservice :負 責 建 立 blockmanager 到遠端其他節點的

blockmanager 的連線,負責對遠端其他節點的 blockmanager 的資料進行讀寫;

每個 blockmanager 建立之後,做的第一件事就是想 blockmanagermaster 進行

註冊,此時 blockmanagermaster 會為其建立對應的 blockmanagerinfo。

使用 blockmanager 進行寫操作時,比如說,rdd 執行過程中的一些中間資料,

或者我們手動指定了 persist(),會優先將資料寫入記憶體中,如果記憶體大小不夠,會

使用自己的演算法,將記憶體中的部分資料寫入磁碟;此外,如果 persist()指定了要

replica,那麼會使用 blocktransferservice 將資料 replicate 一 份 到 其 他 節 點 的

blockmanager 上去。

使用 blockmanager 進行讀操作時,比如說,shuffleread 操作,如果能從本地讀

取,就利用 diskstore 或者 memorystore 從本地讀取資料,但是本地沒有資料的話,

那麼會用 blocktransferservice 與 有 數 據 的 blockmanager 建 立 連 接 , 然 後 用

blocktransferservice 從遠端 blockmanager 讀取資料;例如,shuffle read 操作中,

很有可能要拉取的資料在本地沒有,那麼此時就會到遠端有資料的節點上,找那個

節點的 blockmanager 來拉取需要的資料。

只要使用 blockmanager 執 行 了 數 據 增 刪 改 的 操 作 , 那 麼 必 須 將 block 的

blockstatus 上報到 blockmanagermaster , 在 blockmanagermaster 上會對指定

blockmanager 的 blockmanagerinfo 內部的 blockstatus 進行增刪改操作,從而達到

元資料的維護功能。

spark 乙個非常重要的特性就是共享變數。

預設情況下,如果在乙個運算元的函式中使用到了某個外部的變數,那麼這個變

量的值會被拷貝到每個 task 中,此時每個 task 只能操作自己的那份變數副本。如果

多個 task 想要共享某個變數,那麼這種方式是做不到的。

spark 為此提供了兩種共享變數,一種是 broadcast variable(廣播變數),

另一種是accumulator(累加變數)。broadcast variable 會將用到的變數,僅僅為每個節

點拷貝乙份,即每個 executor 拷貝乙份,更大的用途是優化效能,減少網路傳輸以

及記憶體損耗。accumulator 則可以讓多個 task 共同操作乙份變數,主要可以進行累

加操作。broadcast variable 是共享讀變數,task 不能去修改它,而 accumulator 可以

讓多個 task 操作乙個變數。

廣播變數允許程式設計者在每個 executor 上保留外部資料的唯讀變數,而不是給每

個任務傳送乙個副本。

每個 task 都會儲存乙份它所使用的外部變數的副本,當乙個 executor 上的多個

task 都使用乙個大型外部變數時,對於 executor 記憶體的消耗是非常大的,因此,我

們可以將大型外部變數封裝為廣播變數,此時乙個 executor 儲存乙個變數副本,此

executor 上的所有 task 共用此變數,不再是乙個 task 單獨儲存乙個副本,這在一定

程度上降低了 spark 任務的記憶體占用。 

spark 還嘗試使用高效的廣播演算法分發廣播變數,以降低通訊成本。

spark 提供的 broadcast variable 是唯讀的,並且在每個 executor 上只會有乙個

副本,而不會為每個 task 都拷貝乙份副本,因此,它的最大作用,就是減少變數到

各個節點的網路傳輸消耗,以及在各個節點上的記憶體消耗。此外,spark 內部也使用

了高效的廣播演算法來減少網路消耗。

可以通過呼叫 sparkcontext 的 broadcast()方法來針對每個變數建立廣播變數。

然後在運算元的函式內,使用到廣播變數時,每個 executor 只會拷貝乙份副本了,每

個 task 可以使用廣播變數的 value()方法獲取值。

在任務執行時,executor 並不獲取廣播變數,當 task 執行到 使用廣播變數的代

碼時,會向 executor 的記憶體中請求廣播變數,如下圖所示:

之後 executor 會通過 blockmanager 向 driver 拉取廣播變數,然後提供給 task

進行使用,如下圖所示:

廣播大變數是 spark 中常用的基礎優化方法,通過減少記憶體占用實現任務執行

效能的提公升。

累加器(accumulator):accumulator 是僅僅被相關操作累加的變數,因此可以

在並行中被有效地支援。它們可用於實現計數器(如 mapreduce)或總和計數。

accumulator 是存在於 driver 端的,集群上執行的 task 進行 accumulator 的累加,

隨後把值發到 driver 端,在 driver 端彙總(spark ui 在 sparkcontext 建立時被建立,

即在 driver 端被建立,因此它可以讀取 accumulator 的數值),由於 accumulator

存在於 driver 端,從節點讀取不到 accumulator 的數值。

spark 提供的 accumulator 主要用於多個節點對乙個變數進行共享性的操作。

accumulator 只提供了累加的功能,但是卻給我們提供了多個 task 對於同乙個變數

並行操作的功能,但是 task 只能對 accumulator 進行累加操作,不能讀取它的值,

只有 driver 程式可以讀取 accumulator 的值。

accumulator 的底層原理如下圖所示:

8.總結

spark 的核心原理對於更好的使用 spark 完成開發任務有著非常重要的作用,在

本課程的學習中,我們對 spark 的部署模式、通訊架構、任務排程機制、shuffle 過

程、記憶體管理機制以及 spark 核心元件進行了詳細分析,這些內容都是 spark 最為

重要的架構原理,希望在之後的學習中大家可以不斷深化對於 spark 核心架構的理

解,在更高的層次上去使用 spark 技術框架。

Spark指南 第五章 Spark核心解析(1)

四 任務排程機制 五 訊息通訊原理 六 where to go spark核心泛指spark訊息通訊原理 作業執行原理 儲存原理 執行時架構 記憶體管理機制 任務排程機制等等。4.cluster manager 集群資源管理器 是指在集群上獲取資源的外部服務,目前有支援以下三種 standalone...

spark核心架構

driver部分的 sparkconf sparkcontext driver 部分 val conf new sparkconf val sc new sparkcontext conf end executor部分 分布到集群中的 比如 textfile flatman map worker 管...

Spark核心原理

寬依賴 有shuffle 父rdd的乙個分割槽會被子rdd的多個分割槽所依賴 窄依賴 沒有shuffle 父rdd的乙個分割槽只會被子rdd的1個分割槽所依賴 總結 窄依賴 並行化 容錯 寬依賴 進行階段劃分 shuffle後的階段需要等待shuffle前的階段計算完才能執行 spark的dag 就...