一、寬窄依賴
兩種依賴關係類型
RDD和它依賴的父RDD的關係有兩種不同的類型,即
寬依賴(wide dependency/shuffle dependency)
窄依賴(narrow dependency)
圖解
如何區分寬窄依賴
窄依賴:父RDD的一個分區只會被子RDD的一個分區依賴
寬依賴:父RDD的一個分區會被子RDD的多個分區依賴(涉及到shuffle)
子RDD的一個分區依賴多個父RDD是寬依賴還是窄依賴?
不能確定,也就是寬窄依賴的劃分依據是父RDD的一個分區是否被子RDD的多個分區所依賴,是,就是寬依賴,或者從shuffle的角度去判斷,有shuffle就是寬依賴
爲什麼要設計寬窄依賴
1.對於窄依賴
Spark可以並行計算
如果有一個分區數據丟失,只需要從父RDD的對應1個分區重新計算即可,不需要重新計算整個任務,提高容錯。
2.對於寬依賴
是劃分Stage的依據
二、DAG介紹
DAG是什麼
DAG(Directed Acyclic Graph有向無環圖)指的是數據轉換執行的過程,有方向,無閉環(其實就是RDD執行的流程)
原始的RDD通過一系列的轉換操作就形成了DAG有向無環圖,任務執行時,可以按照DAG的描述,執行真正的計算(數據被操作的一個過程)
DAG的邊界
開始:通過SparkContext創建的RDD
結束:觸發Action,一旦觸發Action就形成了一個完整的DAG
注意:
一個Spark應用中可以有一到多個DAG,取決於觸發了多少次Action
一個DAG中會有不同的階段/stage,劃分階段/stage的依據就是寬依賴
一個階段/stage中可以有多個Task,一個分區對應一個Task
DAG劃分Stage
爲什麼要劃分Stage? --並行計算
一個複雜的業務邏輯如果有shuffle,那麼就意味着前面階段產生結果後,才能執行下一個階段,即下一個階段的計算要依賴上一個階段的數據。那麼我們按照shuffle進行劃分(也就是按照寬依賴就行劃分),就可以將一個DAG劃分成多個Stage/階段,在同一個Stage中,會有多個算子操作,可以形成一個pipeline流水線,流水線內的多個平行的分區可以並行執行
如何劃分DAG的stage
對於窄依賴,partition的轉換處理在stage中完成計算,不劃分(將窄依賴儘量放在在同一個stage中,可以實現流水線計算)
對於寬依賴,由於有shuffle的存在,只能在父RDD處理完成後,才能開始接下來的計算,也就是說需要要劃分stage(出現寬依賴即拆分)
總結
Spark會根據shuffle/寬依賴使用回溯算法來對DAG進行Stage劃分,從後往前,遇到寬依賴就斷開,遇到窄依賴就把當前的RDD加入到當前的stage/階段中
具體的劃分算法請參見AMP實驗室發表的論文
《Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing》