簡要MR與Spark在Shuffle區別


一、區別

①本質上相同,都是把Map端數據分類處理后交由Reduce的過程。

②數據流有所區別,MR按map, spill, merge, shuffle, sort, reduce等各階段逐一實現。Spark基於DAG數據流,可實現更復雜數據流操作(根據寬/窄依賴實現)

③實現功能上有所區別,MR在map中做了排序操作,而Spark假定大多數應用場景Shuffle數據的排序操作不是必須的,而是采用Aggregator機制(Hashmap每個元素<K,V>形式)實現。(下面有較詳細說明)

ps:為了減少內存使用,Aggregator是在磁盤進行,也就是說,盡管Spark是“基於內存的計算框架”,但是Shuffle過程需要把數據寫入磁盤

二、MR中的Shuffle

在MR框架中,Shuffle是連接Map和Reduce之間的橋梁,Map的輸出結果需要經過Shuffle過程之后,也就是經過數據分類以后再交給Reduce進行處理。因此,Shuffle的性能高低直接影響了整個程序的性能和吞吐量。由此可知,Shuffle是指對Map輸出結果進行分區、排序、合並等處理並交給Reduce的過程。因此,MapReduce的Shuffle過程分為Map端的操作和Reduce端的操作,如下圖:

簡單點說: Map端Shuffle過程,就是對Map輸出結果寫入緩存、分區、排序、合並再寫入磁盤。
Reduce端Shuffle過程,就是從不同Map機器取回輸出進行歸並后交給Reduce進行處理。

三、Spark中的Shuffle

①、Spark作為MR框架的改進,也實現了Shuffle的邏輯,如下圖:

Map端的Shuffle寫入(Shuffle Write)方面,每個Map根據Reduce任務的數量創造相應桶數量m*r(桶為抽象概念,m是map任務r是reduce任務),Map任務產生的結果根據分區算法(默認hash)到不同桶中。當Reduce任務啟動時,會根據自己任務的id和所依賴的Map任務的id,從遠端或本地取得對應的桶,作為Reduce任務的輸入進行處理。

ps:在Spark1.2的版本后,Shuffle引擎改為SortShuffleManager(原來為HashShuffleManager),也就是把每個Map任務所有輸出數據都寫到同一個任務中,避免小文件太多對性能的影響。因此Shuffle過程中,每個Map任務會產生數據文件及所有文件兩個。

②、在Reduce端的Shuffle讀取(Shuffle Fetch)方面,大多數場景Spark並不在Reduce端做歸並和排序,而是采用Aggregator機制。Aggregator本質是個HashMap,其中每個元素都是<K,V>形式。

ps:以詞頻統計為例,它會將從Map端拉取到的每一個(key,value),更新或插入到HashMap中。若在HashMap中沒有查找到這個key,則把這個(key,value)插入其中;若找到這個key,則把value的值累加到V上去。這樣就不需要預先把所有的(key,value)進行歸並和排序,而是來一個處理一個,避免外部排序這一步驟。

③、窄依賴寬依賴

以是否包含Shuffle操作為判斷依據,RDD中的依賴關系可以分為窄依賴與寬依賴,區別如下

窄依賴:一個父RDD的分區對應一個子RDD的分區,或者多個父RDD的分區對應一個子RDD的分區。典型操作包括map/filter/union等,不會包含Shuffle操作

寬依賴:一個父RDD的一個分區對應一個子RDD的多個分區。典型操作包括groupByKey/sortByKey等,通常包含Shuffle操作

ps:對於join操作,視情況而定,如上圖左側進行協同划分,屬於窄依賴。如上圖右側做非協同划分,屬於寬依賴。

④、階段划分

Spark根據DAG圖中的RDD依賴關系,把一個作業分成多個階段。參考下圖例子過程:

Stage2為窄依賴,可以把多個fork/join合並為一個,不但減少了大量的全局路障,而且無需保存很多中間結果RDD,可以極大提高性能,該過程叫流水線優化(Pipeline)


學習交流,有任何問題還請隨時評論指出交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM