MapReduce過程、Spark和Hadoop以Shuffle為中心的對比分析

mapreduce與Spark的map-Shuffle-reduce過程

  • mapreduce過程解析(mapreduce采用的是sort-based shuffle)
  • 將獲取到的數據分片partition進行解析,獲得k/v對,之后交由map()進行處理.
  • map函數處理完成之后,進入collect階段,對處理后的k/v對進行收集,存儲在內存的環形緩沖區中。
  • 當環形緩沖區中的數據達到閥值之后(也可能一直沒有達到閥值,也一樣要將內存中的數據寫入磁盤),將內存緩沖區中的數據通過SpillThread線程轉移到磁盤上。需要注意的是,轉移之前,首先利用快排對記錄數據進行排序(原則是先按照分區編號,再按照key進行排序,注意,排序是在寫入磁盤之前的)。之后按照partition編號,獲取上述排序之后的數據并將其寫入Spill.out文件中(一個Spill.out文件中可能會有多個分區的數據--因為一次map操作會有多次的spill的過程),需要注意的是,如果人為設置了combiner,在寫入文件之前,需要對每個分區中的數據進行聚集操作。該文件同時又對應SpillRecord結構(Spill.out文件索引)。
  • map的最后一個階段是merge:該過程會將每一個Spill.out文件合并成為一個大文件(該文件也有對應的索引文件),合并的過程很簡單,就是將多個Spill.out文件的在同一個partition的數據進行合并。(第一次聚合)

  • shuffle階段。首先要說明的是shuffle階段有兩種閥值設置。第一,獲取來自map的結果數據的時候,根據數據大小(file.out的大小)自然劃分到內存或者是磁盤(這種閥值的設置跟map階段完全不同);第二,內存和磁盤能夠保存的文件數目有閥值,超出閥值,會對文件進行merge操作,即小文件合并成為大文件。Shuffle過程:
    1)獲取完成的Map Task列表。
    2)進行數據的遠程拷貝(http get的方法),根據數據文件的大小自然劃分到內存或者是磁盤。
    3)當內存或者磁盤的文件較多時,進行文件合并。(第二次聚合)

  • reduce之前需要進行Sort操作,但是兩個階段是并行化的,Sort在內存或者磁盤中建立小頂堆,并保存了指向該小頂堆根節點的迭代器,同時Reduce Task通過迭代器將key相同的數據順次講給reduce()函數進行處理。
  • Spark Shuffle過程解析(采用hash-based shuffle)
    • RDD是Spark與Hadoop之間最明顯的差別(數據結構),Spark中的RDD具有很多特性,在這里就不再贅述。
    • Spark與Hadoop之間的Shuffle過程大致類似,Spark的Shuffle的前后也各有一次聚合操作。但是也有很明顯的差別:Hadoop的shuffle過程是明顯的幾個階段:map(),spill,merge,shuffle,sort,reduce()等,是按照流程順次執行的,屬于push類型;但是,Spark不一樣,因為Spark的Shuffle過程是算子驅動的,具有懶執行的特點,屬于pull類型。
    • Spark與Hadoop的Shuffle之間第二個明顯的差別是,Spark的Shuffle是hash-based類型的,而Hadoop的Shuffle是sort-based類型的。下面簡介一下Spark的Shuffle:
      1.正因為是算子驅動的,Spark的Shuffle主要是兩個階段:Shuffle Write和Shuffle Read。
      2.ShuffleMapTask的整個的執行過程就是Shuffle Write階段
      3.Sprk的Shuffle過程剛開始的操作就是將map的結果文件中的數據記錄送到對應的bucket里面(緩沖區),分到哪一個bucket根據key來決定(該過程是hash的過程,每一個bucket都對應最終的reducer,也就是說在hash-based下,數據會自動劃分到對應reducer的bucket里面)。之后,每個bucket里面的數據會不斷被寫到本地磁盤上,形成一個ShuffleBlockFile,或者簡稱FileSegment。上述就是整個ShuffleMapTask過程。之后,reducer會去fetch屬于自己的FileSegment,進入shuffle read階段。
      4.需要注意的是reducer進行數據的fetch操作是等到所有的ShuffleMapTask執行完才開始進行的,因為所有的ShuffleMapTask可能不在同一個stage里面,而stage執行后提交是要在父stage執行提交之后才能進行的,所以fetch操作并不是FileSegment產生就執行的。
      5.需要注意的是,剛fetch來的FileSegment存放在softBuffer緩沖區,Spark規定這個緩沖界限不能超過spark.reducer.maxMbInFlight,這里用softBuffer表示,默認大小48MB。
      6.經過reduce處理后的數據放在內存+磁盤上(采用相關策略進行spill)。
      7.fetch一旦開始,就會邊fetch邊處理(reduce)。MapReduce shuffle階段就是邊fetch邊使用combine()進行處理,但是combine()處理的是部分數據。MapReduce不能做到邊fetch邊reduce處理,因為MapReduce為了讓進入reduce()的records有序,必須等到全部數據都shuffle-sort后再開始reduce()。然而,Spark不要求shuffle后的數據全局有序,因此沒必要等到全部數據shuffle完成后再處理。為了實現邊shuffle邊處理,而且流入的records是無序的可以用aggregate的數據結構,比如HashMap。

  • hash-based 和 sort-based的對比

    • hash-based故名思義也就是在Shuffle的過程中寫數據時不做排序操作,只是將數據根據Hash的結果,將各個Reduce分區的數據寫到各自的磁盤文件中。這樣帶來的問題就是如果Reduce分區的數量比較大的話,將會產生大量的磁盤文件(Map*Reduce)。如果文件數量特別巨大,對文件讀寫的性能會帶來比較大的影響,此外由于同時打開的文件句柄數量眾多,序列化,以及壓縮等操作需要分配的臨時內存空間也可能會迅速膨脹到無法接受的地步,對內存的使用和GC帶來很大的壓力,在Executor內存比較小的情況下尤為突出,例如Spark on Yarn模式。但是這種方式也是有改善的方法的:

    在一個core上連續執行的ShuffleMapTasks可以共用一個輸出文件ShuffleFile。先執行完的ShuffleMapTask形成ShuffleBlock i,后執行的ShuffleMapTask可以將輸出數據直接追加到ShuffleBlock i后面,形成ShuffleBlock i’,每個ShuffleBlock被稱為FileSegment。下一個stage的reducer只需要fetch整個ShuffleFile就行了。這樣的話,整個shuffle文件的數目就變為C*R了。

    • sort-based是Spark1.1版本之后實現的一個試驗性(也就是一些功能和接口還在開發演變中)的ShuffleManager,它在寫入分區數據的時候,首先會根據實際情況對數據采用不同的方式進行排序操作,底線是至少按照Reduce分區Partition進行排序,這樣來至于同一個Map任務Shuffle到不同的Reduce分區中去的所有數據都可以寫入到同一個外部磁盤文件中去,用簡單的Offset標志不同Reduce分區的數據在這個文件中的偏移量。這樣一個Map任務就只需要生成一個shuffle文件,從而避免了上述HashShuffleManager可能遇到的文件數量巨大的問題。上述過程與mapreduce的過程類似。
  • 兩者的性能比較,取決于內存,排序,文件操作等因素的綜合影響。

  • 對于不需要進行排序的Shuffle操作來說,如repartition等,如果文件數量不是特別巨大,HashShuffleManager面臨的內存問題不大,而SortShuffleManager需要額外的根據Partition進行排序,顯然HashShuffleManager的效率會更高。
  • 而對于本來就需要在Map端進行排序的Shuffle操作來說,如ReduceByKey等,使用HashShuffleManager雖然在寫數據時不排序,但在其它的步驟中仍然需要排序,而SortShuffleManager則可以將寫數據和排序兩個工作合并在一起執行,因此即使不考慮HashShuffleManager的內存使用問題,SortShuffleManager依舊可能更快。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375

推薦閱讀更多精彩內容