Spark 的架構原理

本文旨在記錄自己所學的大數據知識。本文素材來源於李智慧老師的《從0開始學大數據》,李老師講的大數據課程既有教相關知識的,也有教我們如何學習,如何思考的,講的非常好。

 

Spark 也遵循移動計算比移動數據更划算這一大數據計算基本原則

 

相關概念:計算階段,依賴關係,DAG,Spark應用,任務集合

 

一、Spark的計算階段

1、Spark計算本質上也是Map和reduce組成的。對比MapReduce僵化地把運行劃分成一個Map和一個Reduce。Spark的計算可以由多個Map和多個Reduce組成,Map根據業務需求把計算任務劃分爲多個階段,每個階段根據依賴關係組成一個DAG(有向無環圖),Spark任務調度器根據DAG依賴關係進行運算。舉個栗子,有些迴歸算法需要進行多個迭代計算,產生數萬個計算階段,這些計算階段可以在一個Spark應用中處理,如果使用MapReduce處理,則需要產生數萬個MapReduce。

2、DAG依賴,即有向無環圖。

1⃣️依賴是有向的,不能組成一個環形依賴,環形依賴會進入死循環。

2⃣️被依賴的階段要先執行完,依賴的階段才能開始執行。Spark執行自然會沿着依賴關係執行。

栗子:下圖是一個DAG,劃分爲3個階段,階段3依賴階段1和階段2。階段1和階段2互相不依賴。只需要建立好依賴關係,計算時就能按順序執行,階段1和階段2運行完成以後,階段3才能開始執行。更多階段運行同理。

上圖這個DAG中各個階段的僞代碼如下:

rddB = rddA.groupBy(key)

rddD = rddC.map(func)

rddF = rddD.union(rddE)

rddG = rddB.join(rddF)

 

所以,可以看到Spark運算的核心是DAG,有了DAG,就可以把它根據依賴關係劃分爲各個有序計算階段,每個階段又根據要處理的數據量生成相應的任務集合(TaskSet),每一個任務分配一個任務進程去執行,Spark就實現了大數據分佈式計算了。

 

3⃣️具體地,生成DAG的組件是DAGScheduler。DAGScheduer根據程序代碼生成DAG,然後把程序分發到分佈式集羣上運行,各個運算階段根據依賴關係執行。

4⃣️階段依賴中分爲兩種依賴,寬依賴和窄依賴。經過shuffle過程的依賴爲寬依賴,如階段2和階段3之間,rddG和rddF之間是寬依賴。不經過shuffle階段的依賴叫做窄依賴,如階段1和階段3之間,rddG和rddB之間的是窄依賴。

 

3:那麼Spark劃分階段的依據是什麼?

不是計算函數,有些函數會產生新階段,有些不會。從圖中可以觀察出是shuffle。如A和B之間被shuffle切開,shuffle之前的算一個階段;F和G之間被shuffle切開,shuffle之前的即CDEF算一個階段。整個運算要執行完B和F需要合併成G,這算一個大的階段。

 

4:同樣經過shuffle,爲什麼Spark比MapReduce更加高效?

1⃣️spark不固化爲一個Map和一個Reduce,可以根據業務需求組合多個Map、Reduce來形成一個連貫的計算任務。更加靈活,更加適合複雜的計算任務。MapReduce則固化爲一個Map和一個Reduce,執行復雜任務時需要多個MapReduce組合。

2⃣️spark能使用內存就不會使用磁盤,MapReduce的job和job之間的數據交互都是通過磁盤的,spark的一個job和另一個job本身就是同屬一個計算任務,所以job和job之間的數據交互優先使用磁盤交互,所以spark更加快。

二、Spark作業管理

Spark中RDD函數有兩種,一種是轉換(transform)函數,一種是action函數。

轉換函數:調用以後還是返回一個RDD,spark計算邏輯主要通過轉換函數完成。

action函數:調用以後返回一個job,調用以後馬上會運行。

Spark的DAGScheduler在遇到shuffle的時候會生成一個計算階段,在遇到action函數時會生成一個作業(job).

 

關於作業、計算階段、任務的依賴和時間的先後,如下圖:

 

橫軸是時間,縱軸是任務。兩條粗黑線之間是作業,兩條細黑線之間是計算階段,細小紅線是任務。

一個作業至少包含一個計算階段,一個計算階段包含多個任務。

 

那麼Spark的作業管理究竟跟spark的函數有什麼關係呢?

spark的作業是DAGScheduler根據代碼(函數)來生成的。即DAG(有向無環圖)--> 依賴關係 --> 計算階段 --> 計算任務。

 

得到計算任務後,spark任務調度會以任務爲單位,把各個任務分配到不同的機器上面執行。

 

三、Spark的執行過程(運行流程)

 

Spark支持幾種部署模式:standalone、Yarn、Mesos、Kubernetes。幾種部署模式的執行過程都一樣,只是角色的名字不同。下面介紹Spark的執行過程。

上圖爲Spark部署圖。DriverProgram是Spark的客戶端程序,是一個JVM應用。Driver Program是整個運行過程的核心。

 

步驟:

1、客戶端Driver Program中SparkContext調用DAGScheduler計算得出DAG圖,從而最終得到作業的最小執行單元——任務。

2、Driver Program帶着主機地址等信息向Cluster Manager請求計算資源。

3、Cluster Manager向集羣中的所有Worker發送通知,告知它們Driver Program的地址信息。

4、收到通知的Worker會根據主機地址註冊到Driver Program。並且根據自身的空閒資源向Cluster Manager通報自己能認領的任務數。Driver Program根據DAG圖向已註冊的Worker分配任務。

5、Worker收到任務後,會啓動Executor進程準備執行任務。Executor會先檢查自身是否存在Driver 的任務程序(作業jar包),如果不存在的話會先向Driver Program下載任務程序,通過Java反射加載程序並執行。

 

總結,Spark相比MapReduce來說有三個特性,

1、Spark的編程模型更加靈活、高效。

2、DAG切分的多階段比多個MapReduce速度快得多。

3、Spark優先使用內存進行數據中間交換,速度更快。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章