其他更多java基礎文章:
java基礎學習(目錄)
窄依賴和寬依賴
窄依賴:
指父RDD的每一個分割槽最多被一個子RDD的分割槽所用,表現為一個父RDD的分割槽對應於一個子RDD的分割槽,和兩個父RDD的分割槽對應於一個子RDD 的分割槽。圖中,map/filter和union屬於第一類,對輸入進行協同劃分(co-partitioned)的join屬於第二類。
寬依賴:
指子RDD的分割槽依賴於父RDD的所有分割槽,這是因為shuffle類操作,如圖中的groupByKey和未經協同劃分的join。
DAG
DAG,有向無環圖,Directed Acyclic Graph的縮寫,常用於建模。Spark中使用DAG對RDD的關係進行建模,描述了RDD的依賴關係,這種關係也被稱之為lineage,RDD的依賴關係使用Dependency維護,參考Spark RDD之Dependency,DAG在Spark中的對應的實現為DAGScheduler。
Stage
在spark中,會根據RDD之間的依賴關係將DAG圖劃分為不同的階段,一個Job會被拆分為多組TaskSet,每組任務被稱為一個Stage。對於窄依賴,由於partition依賴關係的確定性,partition的轉換處理就可以在同一個執行緒裡完成,窄依賴就被spark劃分到同一個stage中,而對於寬依賴,只能等父RDD shuffle處理完成後,下一個stage才能開始接下來的計算。
Stage劃分思路
-
因此spark劃分stage的整體思路是:從後往前推,遇到寬依賴就斷開,劃分為一個stage;遇到窄依賴就將這個RDD加入該stage中。因此在上圖中RDD C,RDD D,RDD E,RDDF被構建在一個stage中,RDD A被構建在一個單獨的Stage中,而RDD B和RDD G又被構建在同一個stage中。
-
在spark中,Task的型別分為2種:ShuffleMapTask和ResultTask;
- ResultTask:對於 DAG 圖中最後一個 Stage(也就是 ResultStage),會生成與該 DAG 圖中哦最後一個 RDD (DAG 圖中最後邊)partition 個數相同的 ResultTask
- ShuffleMapTask:對於非最後的 Stage(也就是 ShuffleMapStage),會生成與該 Stage 最後的 RDD partition 個數相同的 ShuffleMapTask
-
每個Stage裡面的Task的數量是由該Stage中最後一個RDD的Partition的數量所決定的
注意:同一個Stage的執行是序列的,比如Stage2的RDD C-D-F中,假設只有一個CPU core ,Spark是先將一條資料按C-D-F的順序執行完後,再執行下一條資料。而不是將所有資料從RDD C中計算到RDD D了,再往下計算RDD F。
總結
RDD的寬窄依賴的劃分是為了劃分Stage,劃分Stage是為了Pipline計算模型的實現,Pipline的計算模式能夠以一種管道流的方式,以高階函式的形式實現資料的本地化,傳邏輯而不傳輸資料。在Pipline計算模式遇到持久化運算元或者Shuffle(寬依賴運算元)時候就會產生資料的落地。