0x01 寬依賴和窄依賴
窄依賴:
父RDD的每個分區(qū)最多被子RDD的一個分區(qū)所用(一個父RDD分區(qū)對應一個子RDD分區(qū)),即父RDD的數(shù)據(jù)沒有被重新規(guī)劃分區(qū)(沒有被重新洗牌)。
寬依賴:
父RDD的每一個分區(qū)被子RDD的所有分區(qū)所用(一個父RDD分區(qū)的數(shù)據(jù)被分發(fā)到子RDD的所有分區(qū)),即父RDD的數(shù)據(jù)被重新規(guī)劃分區(qū)(被重新洗牌)。
兩種RDD依賴的關系圖如下所示:

0x02 Stage
RDD在執(zhí)行action操作時,會觸發(fā)Job的提交,Spark會根據(jù)RDD的DAG圖,將Job劃分成多個階段,每個階段稱為一個Stage。
Stage分為兩種:Shuffle Map Stage和Result Stage。
Shuffle Map Stage:case its tasks' results are input for other stage(s)——Shuffle Map Stage階段的task結(jié)果被輸入到其他Stage。
Result Stage:Result Stage階段的task結(jié)果直接是job的結(jié)果,也就是說包含最后一個RDD的Stage就是Result Stage。
Shuffle Map Stage中的Task稱為ShuffleMapTask,Result Stage中的Task稱為ResultTask。
0x03 Stage的劃分
Spark的Job會根據(jù)RDD的依賴關系來劃分Stage,劃分Stage的整體邏輯是:
從最后一個RDD往前推,遇到窄依賴的父RDD時,就將這個父RDD加入子RDD所在的stage;遇到寬依賴的父RDD時就斷開,父RDD被劃分為新的stage。

為什么遇到寬依賴需要切分Stage?
原因是:保證同一個Stage中的所有Task可以并行執(zhí)行。
對于窄依賴,父子RDD的partition依賴關系是一對一,所以將子RDD的partition和其依賴的父RDD的partition放在同一個線程里處理,不同的線程可以并行的執(zhí)行不同partition的轉(zhuǎn)換處理。
而對于寬依賴,因為子RDD的每個partition都依賴父RDD的所有partition,所以子RDD的partition轉(zhuǎn)換處理需要等父RDD的所有partition處理完成才能開始。所以寬依賴的父RDD不能和子RDD放在同一個Stage中。