開門見山,本文就針對一個點,談談Spark中的寬依賴和窄依賴,這是Spark計算引擎劃分Stage的根源所在,遇到寬依賴,則劃分爲多個stage,針對每個Stage,提交一個TaskSet:
上圖:一張網上的圖:
基於此圖,分析下這裏爲什麼前面的流程都是窄依賴,而後面的卻是寬依賴:
我們仔細看看,map和filter算子中,對於父RDD來說,一個分區內的數據,有且僅有一個子RDD的分區來消費該數據。
同樣,UNION算子也是同樣的:
所以,我們判斷窄依賴的依據就是:父類分區內的數據,會被子類RDD中的指定的唯一一個分區所消費:
這是很重要的:
面試的時候,面試官問到了一個問題,如果父類RDD有很多的分區,而子類RDD只有一個分區,我們可以使用repartition或者coalesce算子來實現該效果,請問,這種實現是寬依賴?還是窄依賴?
如果從網上流傳的一種觀點:子RDD一個partition內的數據依賴於父類RDD的所有分區,則爲寬依賴,這種判斷明顯是錯誤的:
別笑,網上的確有這種說法,我差點栽了跟頭,這種解釋實質上是錯誤的,因爲如果我們的reduceTask只有一個的時候,只有一個分區,這個分區內的數據,肯定依賴於所有的父類RDD:
毫無疑問,這是個窄依賴:
相對之下,什麼是寬依賴呢?
寬依賴,指的是父類一個分區內的數據,會被子RDD內的多個分區消費,需要自行判斷分區,來實現數據發送的效果:
總結一下:
窄依賴:父RDD中,每個分區內的數據,都只會被子RDD中特定的分區所消費,爲窄依賴:
寬依賴:父RDD中,分區內的數據,會被子RDD內多個分區消費,則爲寬依賴:
這裏,還存在一個可能被挑刺的地方,比如說父類每個分區內都只有一個數據,毫無疑問,這些數據都會被唯一地指定到子類的某個分區內,這是窄依賴?還是寬依賴?
這時候,可以從另外一個角度來看問題:
每個分區內的數據,是否能夠指定自己在子類RDD中的分區?
如果不能,那就是寬依賴:如果父RDD和子RDD分區數目一致,那基本就是窄依賴了:
總之,還是要把握住根本之處,就是父RDD中分區內的數據,是否在子類RDD中也完全處於一個分區,如果是,窄依賴,如果不是,寬依賴。
————————————————
版權聲明:本文爲CSDN博主「土豆釗」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u013384984/article/details/80963455