Spark深入淺出之從物理執行角度看Spark

一、思考pipeline

即使採用pipeline的方式,函數f對依賴的RDD中的數據集合的操作也會有兩種方式:

1、f (record) ,f作用於集合的每一條記錄,每次只作用於一條記錄

2、f(records),f 一次性作用於集合的全部數據。

Spark採用的是第一種方式,原因:

1、無需等待,可以最大化的使用集羣的計算資源。

2、減少OOM的發生。

3、最大化的有利於併發。

4、可以精準的控制每一個Partition本身(Dependency)及其內部的計算(compute)。

5、基於lineage的算子流動式函數式編程,節省了中間結果的產生。並且可以最快的恢復。

疑問:會不會增加網絡通信? 不會!因爲在pipeline(在stage內部把很多算子合併成一個)

二、思考Spark Job具體的物理執行

SparkApplication裏面可以產生1個或者多個job,例如spark-shell默認啓動的時候內部就沒有job,只是作爲資源的分配程序,可以在spark-shell裏面寫代碼產生若干個job,普通程序中一般而言可以有不同的Action,每一個Action一般也回觸發一個Job .

Spark是MapReduce思想的一種更加精緻和高效的實現,MapReduce有很多具體不同的實現,例如Hadoop的MapReduce基本的計算流程如下:首先是以JVM爲對象的併發執行的mapper,Mapper中的map的執行會產生輸出數據,輸出數據會經過Partitionner指定的規則放到Local FileSystem,然後再經由shuffle,sort,aggregate變成Reducer中reduce的輸入,執行reduce產生最終的執行結果;hadoop MapReduce執行的流程雖然簡單,但是過於死板,尤其是在構造複雜算法(迭代)時候非常不利於算法的實現,且執行效率極爲低下。

Spark算法構造和物理執行是最最基本的核心:最大化pipeline

基於pipelien的思想,數據被使用的時候纔開始計算,

從數據流動的視角來說,是數據流動到計算的位置。實質上從邏輯的角度來看,是算子在數據上流動。

從算法構建的角度而言:肯定是算子作用於數據,所以是算子在數據上流動,方便算法的構建;

從物理執行的角度而言,是數據流動到計算的位置。方便系統最爲高效的運行。

對於pipeline而言,數據計算的位置就是每個stage中最後的RDD,每個stage中除了最後一個RDD算子是真實的意外,前面的算子都是假的。

由於計算的lazy特性,導致計算從後往前回溯,形成computing Chain(鏈條計算),導致的結果就是需要首先計算出具體一個stage內部最左側的RDD中本次計算依賴的Partition

三、窄依賴的物理執行內幕

一個stage內部的RDD都是窄依賴,窄依賴計算本身是從邏輯上看是從stage內部最左側的RDD開始立即計算的,根據computing chain,數據(Record)從一個計算步驟流動到 下一個計算步驟,以此類推,直到計算到 stage內部的最後一個RDD 來產生計算結果。

Computing Chain的構建是從後往前回溯構建而成的,而實際的物理計算則是讓數據從前往後在算子上流動,直到流動 到不能再流動爲止纔開始計算下一個Record。後面的RDD 對前面RDD的依賴雖然是Partition級別的數據集合的依賴,但是並不需要父RDD把Partition中所有的Records計算完畢才整體往後流動數據進行計算。這就極大的提高了計算效率 源碼爲

class MapPartitionsRDD

override def compute(split: partition,context:TaskContext):Iterator[U] = f(context,split.index,firstParent[T].iterator(split,context))

四:寬依賴物理執行內幕:

必須等到依賴的父Stage中的最後一個RDD把全部數據徹底計算完畢,才能夠經過Shuffle來計算當前的Stage.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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