大數據計算框架——MapReduce(內含詳細的shuffle過程)

1. MapReduce模型簡介

MapReduce同樣是谷歌公司的MapReduce的開源實現,其要比谷歌的MapReduce的使用門檻低很多。MapReduce將複雜的、運行於大規模集羣上的並行計算過程高度地抽象到兩個函數:Map和Reduce函數。

主要思想:“分而治之”+計算向數據靠攏。一個存儲在分佈式文件系統中的大規模數據集,在處理之前將會被切分成爲許多獨立的小數據塊,這小小的數據塊會被多個Map任務並行處理。MapReduce框架會爲每個Map任務輸入一個數據集,Map任務的結果會繼續作爲Reduce任務的輸入,最終由Reduce任務輸出最後的結果,並寫入分佈式文件系統。前提條件:待處理的數據可以分解成爲許多的小的數據集,而且每個小的數據集可以並行的進行處理。

計算向數據靠攏:在一個集羣中,只要有可能,MapReduce框架就會將Map程序就近地在HDFS數據所在的數據節點運行,即將計算節點和存儲節點在一起運行。

2. Map 和 Reduce 函數

二者是Hadoop模型的核心,二者是由程序員開發者負責具體實現的。程序員只需要關注這兩個函數如何編寫,而不需要處理並行編程中的其他各種複雜的問題,如分佈式存儲、工作調度等都會由MapReduce框架進行處理。

2.1 Map函數

輸入來源於分佈式文件系統的文件塊,這些文件塊的格式是任意的,可以是文檔,也可以是二進制格式的。文件塊是一系列元素的集合,這些元素的類型也是任意的。Map函數將輸入的元素轉換爲 <key,value>形式的鍵值對,鍵和值的類型也是任意的,但其中的鍵值不作爲標誌性屬性,沒有唯一性,不同的鍵值對的key值可以相同,一個Map函數可以生成多個具有相同key值的<key,value>對。

2.2 Reduce函數

其輸入爲Map函數的結果,<key,List(value)>對,這種類型的鍵值對所代表的意思是List(value)是一批同屬於同一個key值的value。

Reduce函數將一些列具有相同的鍵值的鍵值對以某種方式組合起來,輸出處理後的鍵值對,輸出的結果爲一個文件。用戶可以指定Reduce函數的個數。

2.3 兩個函數的關係圖

在這裏插入圖片描述

3. MapReduce工作流程

3.1 工作流程概述(注意兩點)

MapReduce的輸入和輸出都需要依賴於分佈式文件系統,輸入的數據塊來源於分佈式文件系統,輸出存儲與分佈式文件系統的不同的節點上。

流程:一個大的MapReduce作業:

(1)首先會被拆分成許多個Map任務在多臺機器上並行執行,每個Map任務通常運行在數據存儲的節點上,這樣計算就向數據靠攏。
(2)當Map任務運行結束後,生成許多<key,value>這樣的中間結果。
(3)這些中間結果會被分發到多個Reduce任務在多臺機器上並行執行,具有相同key值的<key,value>對將會被髮送給同一個Reduce進行處理。
(4)最終將結果保存至分佈式文件系統中,進行輸出。

注意:不同的Map人物之間不會進行通信,不同的Reduce任務之間也不會進行通信。

Map任務的中間結果保存在本地的內存之中。

3.2 工作流程圖片說明

在這裏插入圖片描述

4. MapReduce執行的各個階段

4.1 自己總結的畫的文字配圖(共6個階段)

有什麼不理解的地方可以評論私聊。
在這裏插入圖片描述

5. Shffle過程詳解

Shuffle過程是整個MapReduce工作流程的核心,理解其過程的基本原理,對於理解MapReduce的真個流程來說至關重要。

5.1 Shuffle過程簡介

所謂shuffle,是指對Map輸出結果進行分區,排序,合併,等處理並交給Reduce的過程,分爲Map端的shuffle和Reduce端的shuffle。

5.1.1 shuffle過程圖

在這裏插入圖片描述

5.1.2 shuffle過程講解

  1. Map端的shuffle。
    (1)Map的輸出結果首先會被寫入緩存當中。
    (2)當緩存滿時,便會啓動溢寫操作(這裏的緩存滿並不是緩存真的滿了,而是達到了一定的溢寫比,比如設置當緩存的實用程度達到了80%,便啓動了溢寫操作,剩下的20%的內存接着來存放數據),把緩存中的數據寫入磁盤當中,並清空緩存。
    (3)當啓動溢寫操作的時候,先將緩存中的數據進行分區,然後對每個分區的數據進行排序,合併,之後再寫入磁盤文件。
    (4)每次溢寫便會生成一個新的磁盤文件,Map任務數量的增多,磁盤文件的數量也會跟着增多,最後這些磁盤文件將會被歸併爲一個大的磁盤文件。
  2. Reduce端的shuffle
    Reduce任務從Map端的不同Map機器領回屬於自己的處理的數據,然後對數據進行歸併,後交給Reduce處理。

5.2 Map端的Shffle過程

(1)輸入數據和執行Map任務。

輸入的數據一般是從分佈式文件系統中而來的,一般是以文件塊的形式,文件塊的格式時任意的,可以是文檔,也可以是二進制。Map任務接受<key,value>作爲輸入後,按照一定的規則映射爲一批<key,value>進行輸出。

(2)寫入緩存。

每個Map任務都會被分配一個緩存,Map的輸出結果不是立即寫入磁盤,而是首先寫入緩存當中。在緩存中積累了一定數量的Map輸出結果後,再一次批量性的寫入磁盤,這樣可以大大減少對磁盤的I/O影響。注意:在寫入緩存之前,key與value值都會被序列化爲字節數組。

(3)溢寫(分區,排序,合併(歸併))。

MapReduce的緩存容量是有限的,默認大小是100MB。隨着Map任務的執行,緩存中的Map結果的數量會不斷的增加,當達到一定的溢寫比時,就必須啓動溢寫操作,把緩存中的內容一次性的寫入磁盤中,並清空緩存。溢寫的過程通常是由另一個單獨的後臺線程來完成的,不會影響Map結果往緩存中寫入。

在溢寫到磁盤之前,緩存中的數據首先會被分區。緩存中的數據是<key,value>形式的鍵值對。MapReduce通過Partitioner接口對這些鍵值對進行分區,默認採用的分區方式是Hash函數對key進行哈希後再用Reduce任務的數量進行取模,這樣,就可以把map輸出結果均勻地分配給等量的Reduce任務去並行處理了。當然,MapReduce也允許用戶通過重載Partitioner接口來自定義分區方式。

對於每個分區內的所有鍵值,後臺線程會根據值對他們進行排序,排序是MapReduce的默認操作。排序後根據用戶是否定義函數Combiner來選擇是否執合併函數,如有定義則執行,如沒有則不執行。

(4)文件歸併。

每次溢寫都會生成一個新的溢寫文件在磁盤中,隨着MapReduce的執行,溢寫文件會越來越多,最終,在Map任務全部結束之前,系統會對所有溢寫文件中的數據進行歸併爲一個大文件,生成一個大的溢寫文件,這個大的溢寫文件中的左右的鍵值對也是經過分區和排序的。

5.2.1 合併操作(補充)

所謂合併,就是將那些具有相同key的<key,value>的value加起來,比如:<a,1><a,2>合併爲<a,2>

5.2.2 歸併操作(補充)

所謂歸併,就是講那些具有相同key的鍵值對會被歸併成一個新的鍵值對。比如:<a,1><a,2>歸併爲<a,<1,2>>

5.3 Reduce端的shuffle

只需要從Map端讀取Map結果,然後執行歸併操作,最後輸送給Reduce任務進行處理。

(1)“領取數據”。

Map端的Shuffle過程結束後,所有Map輸出結果都保存在Map端的本地磁盤當中,所以Reduce任務首先要把這些數據請求拉回本地磁盤上。

(3)歸併數據。

從Map端領取回來的數據首先會被保存在Reduce本地的緩存當中,如果緩存滿,就會像Map端一樣被溢寫到磁盤當中。系統中一般存在多個Map機器,Reduce任務會從多個Map機器領回屬於自己處理的那些分區的數據。當溢寫操作啓動的時候,具有相同key值的鍵值對會被執行歸併操作,如用戶定義合併函數,則也會執行合併操作。溢寫文件的增多,最終也會歸併爲一個大的磁盤文件,歸併的時候還會給鍵值對進行排序。

(4)把數據輸入給Reduce任務。

將大的排序,歸併(合併)好的大的磁盤文件輸入給Reduce任務,Reduce任務會執行Reduce函數中定義的各種映射,輸出最終的結果,並保存到分佈式文件系統當中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章