Spark中RDD的高效與DAG(有向無環(huán)圖)有很大的關(guān)系,在DAG調(diào)度中需要對計算的過程劃分Stage,劃分的依據(jù)就是RDD之間的依賴關(guān)系。RDD之間的依賴關(guān)系分為兩種搞旭,寬依賴(wide dependency/shuffle dependency)和窄依賴(narrow dependency)
1.窄依賴
窄依賴就是指父RDD的每個分區(qū)只被一個子RDD分區(qū)使用,子RDD分區(qū)通常只對應(yīng)常數(shù)個父RDD分區(qū),如下圖所示【其中每個小方塊代表一個RDD Partition】
窄依賴.png
窄依賴有分為兩種:
- 一種是一對一的依賴肄渗,即OneToOneDependency
- 還有一個是范圍的依賴镇眷,即RangeDependency,它僅僅被org.apache.spark.rdd.UnionRDD使用翎嫡。UnionRDD是把多個RDD合成一個RDD欠动,這些RDD是被拼接而成,即每個parent RDD的Partition的相對順序不會變惑申,只不過每個parent RDD在UnionRDD中的Partition的起始位置不同
2.寬依賴
寬依賴就是指父RDD的每個分區(qū)都有可能被多個子RDD分區(qū)使用具伍,子RDD分區(qū)通常對應(yīng)父RDD所有分區(qū),如下圖所示【其中每個小方塊代表一個RDD Partition】
寬依賴.png
3.窄依賴與窄依賴比較
- 寬依賴往往對應(yīng)著shuffle操作圈驼,需要在運行的過程中將同一個RDD分區(qū)傳入到不同的RDD分區(qū)中人芽,中間可能涉及到多個節(jié)點之間數(shù)據(jù)的傳輸,而窄依賴的每個父RDD分區(qū)通常只會傳入到另一個子RDD分區(qū)绩脆,通常在一個節(jié)點內(nèi)完成萤厅。
- 當(dāng)RDD分區(qū)丟失時,對于窄依賴來說靴迫,由于父RDD的一個分區(qū)只對應(yīng)一個子RDD分區(qū)惕味,這樣只需要重新計算與子RDD分區(qū)對應(yīng)的父RDD分區(qū)就行。這個計算對數(shù)據(jù)的利用是100%的
- 當(dāng)RDD分區(qū)丟失時矢劲,對于寬依賴來說赦拘,重算的父RDD分區(qū)只有一部分?jǐn)?shù)據(jù)是對應(yīng)丟失的子RDD分區(qū)的慌随,另一部分就造成了多余的計算芬沉。寬依賴中的子RDD分區(qū)通常來自多個父RDD分區(qū),極端情況下阁猜,所有父RDD都有可能重新計算丸逸。如下圖,par4丟失剃袍,則需要重新計算par1,par2,par3,產(chǎn)生了冗余數(shù)據(jù)par5
分區(qū)丟失.png
4.寬依賴黄刚,窄依賴函數(shù)
- 窄依賴的函數(shù)有:
map, filter, union, join(父RDD是hash-partitioned ), mapPartitions, mapValues - 寬依賴的函數(shù)有:
groupByKey, join(父RDD不是hash-partitioned ), partitionBy