Spark2.3.2原始碼解析: 5. RDD 依賴關係:寬依賴與窄依賴
Spark中RDD的高效與DAG(有向無環圖)有很大的關係,在DAG排程中需要對計算的過程劃分Stage,劃分的依據就是RDD之間的依賴關係。RDD之間的依賴關係分為兩種,寬依賴(wide dependency/shuffle dependency)和窄依賴(narrow dependency)
1.窄依賴
窄依賴就是指父RDD的每個分割槽只被一個子RDD分割槽使用,子RDD分割槽通常只對應常數個父RDD分割槽,如下圖所示【其中每個小方塊代表一個RDD Partition】
窄依賴有分為兩種:
- 一種是一對一的依賴,即OneToOneDependency
- 還有一個是範圍的依賴,即RangeDependency,它僅僅被org.apache.spark.rdd.UnionRDD使用。UnionRDD是把多個RDD合成一個RDD,這些RDD是被拼接而成,即每個parent RDD的Partition的相對順序不會變,只不過每個parent RDD在UnionRDD中的Partition的起始位置不同
OneToOneDependency 程式碼:
RangeDependency 程式碼
RangeDependency 和 OneToOneDependency 最大的區別是實現方法中出現了 outStart 、length 、 in start ,
子 RDD 在通過 getParents 方法查詢對應的 Partition 時,會根據這個 partitionld減去插入時的開始 ID,
再加上它在父 RDD 中的位置 D,換而言之,就是將父 RDD 中的Partition ,
根據 partitionld 的順序依插入到子 RDD 中 。
2.寬依賴
RDD 的 寬依賴( Shuffle Dependency )是一種會導致計算時產生 Shuffle 操作的 RDD 操作,
用來表示一個父 RDD 的 Partition 都會被多個子 RDD 的 Partition 使用,
如圖 3-2 寬依賴關係圖 中 groupByKey 運算元操作所示,父 RDD 有 3 個 Partition,
每個 Partition 中的資料會被子RDD 中的兩個 Partition 使用 。
ShuffleDependency 原始碼:
3.窄依賴與窄依賴比較
- 寬依賴往往對應著shuffle操作,需要在執行的過程中將同一個RDD分割槽傳入到不同的RDD分割槽中,中間可能涉及到多個節點之間資料的傳輸,而窄依賴的每個父RDD分割槽通常只會傳入到另一個子RDD分割槽,通常在一個節點內完成。
- 當RDD分割槽丟失時,對於窄依賴來說,由於父RDD的一個分割槽只對應一個子RDD分割槽,這樣只需要重新計算與子RDD分割槽對應的父RDD分割槽就行。這個計算對資料的利用是100%的
- 當RDD分割槽丟失時,對於寬依賴來說,重算的父RDD分割槽只有一部分資料是對應丟失的子RDD分割槽的,另一部分就造成了多餘的計算。寬依賴中的子RDD分割槽通常來自多個父RDD分割槽,極端情況下,所有父RDD都有可能重新計算。如下圖,par4丟失,則需要重新計算par1,par2,par3,產生了冗餘資料par5
4.寬依賴,窄依賴函式
- 窄依賴的函式有:
map, filter, union, join(父RDD是hash-partitioned ), mapPartitions, mapValues - 寬依賴的函式有:
groupByKey, join(父RDD不是hash-partitioned ), partitionBy
5.例項
參考資料: