1. 程式人生 > >Spark2.3.2原始碼解析: 5. RDD 依賴關係:寬依賴與窄依賴

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.例項


 

參考資料:

https://www.jianshu.com/p/5c2301dfa360