好程式設計師大資料學習路線分享MapReduce全過程解析

好程式設計師IT發表於2019-08-28

  好程式設計師大資料學習路線分享MapReduce 全過程解析,移動資料與移動計算

   在學大資料的時候接觸了移動資料和移動計算這兩種聯絡緊密而又有很大不同的概念,其中移動計算也叫做本地計算。

  在以前的資料處理中時使用的移動資料,其實就是將需要處理的資料傳輸到存放不同處理資料方式邏輯的各個節點上。這樣做的效率很低,特別是大資料中的資料量是很大的,至少都是GB 以上,更大的是 TB PB 甚至更大,而且磁碟 I/O 、網路 I/O 的效率是很低的,這樣處理起來就需要很長的時間,遠遠不能滿足我們的要求。而移動計算就出現了。

  移動計算,也叫做本地計算,是資料就存放在節點上不再變動,而是將處理邏輯程式傳輸到各個資料節點上。由於處理程式的大小肯定不會特別的大,這樣就可以實現很快將程式傳輸到存放資料的各個節點上去,然後本地執行處理資料,效率高。現在的大資料處理技術都是採用這種方式。

 

言簡意賅的說:

Map 階段:

1 Read :讀取資料來源,將資料進行 filter 成一個個的 K/V

2 Map :在 map 函式中,處理解析的 K/V ,併產生新的 K/V

3 Collect :輸出結果,存於環形內緩衝區

4 Spill :記憶體區滿,資料寫到本地磁碟,並生產臨時檔案

5 Combine :合併臨時檔案,確保生產一個資料檔案

 

Reduce 階段:

1 Shuffle Copy 階段, Reduce Task 到各個 Map Task 遠端複製一分資料,針對某一份資料, 2 若其大小超過一定閥值,則寫磁碟;否則放到記憶體

3 Merge :合併記憶體和磁碟上的檔案,防止記憶體佔用過多或磁碟檔案過多

4 Sort Map Task 階段進行區域性排序, Reduce Task 階段進行一次歸併排序

5 Reduce :將資料給 reduce 函式

6 Write reduce 函式將其計算的結果寫到 HDFS

 

深度解析的說:

MapTask 階段

1)Read階段 MapTask透過使用者編寫的 RecordReader ,從輸入 InputSplit 中解析出一個個key/value。 

2)Map階段 :該節點主要是將解析出的key/value交給使用者編寫 map()函式 處理,併產生一系列新的key/value。

3)Collect收集階段 :在使用者編寫map()函式中,當資料處理完成後,一般會呼叫 OutputCollector.collect() 輸出結果。在該函式內部,它會將生成的key/value分割槽(呼叫 Partitioner ),並寫入一個 環形記憶體緩衝區 中。 

4)Spill階段 :即“溢寫”,當環形緩衝區滿後,MapReduce 會將資料寫到 本地磁碟 上,生成一個臨時檔案。需要注意的是,將資料寫入本地磁碟之前,先要對資料進行一次 本地排序 ,並在必要時對資料進行 合併、壓縮 等操作。

 

溢寫階段詳情:

步驟1:利用 快速排序演算法 對快取區內的資料進行排序,排序方式是,先按照分割槽編號 partition 進行排序,然後按照key進行排序。這樣,經過排序後,資料以分割槽為單位聚集在一起,且同一分割槽內所有資料按照key有序。 

步驟2:按照分割槽編號由小到大依次將每個分割槽中的資料寫入任務工作目錄下的臨時檔案output/spillN.out(N表示當前溢寫次數)中。如果使用者設定了 Combiner ,則寫入檔案之前,對每個分割槽中的資料進行一次聚集操作。 

步驟3:將分割槽資料的元資訊寫到記憶體索引資料結構 SpillRecord 中,其中每個分割槽的元資訊包括在臨時檔案中的偏移量、壓縮前資料大小和壓縮後資料大小。如果當前記憶體索引大小超過1MB,則將記憶體索引寫到 output/spillN.out.index中。 

(5) Combin e 階段 :當所有資料處理完成後,MapTask對所有臨時檔案進行一次 合併 ,以確保最終 只會生成一個資料檔案 。當所有資料處理完後,MapTask會將所有臨時檔案合併成一個大檔案,並儲存到檔案 output/file.out 中,同時生成相應的 索引檔案output/file.out.index 。在進行檔案合併過程中,MapTask以分割槽為單位進行合併。對於某個分割槽,它將採用 多輪遞迴合併 的方式。每輪合併io.sort.factor(預設100)個檔案,並將產生的檔案重新加入待合併列表中,對檔案排序後,重複以上過程,直到最終得到一個大檔案。讓每個MapTask最終只生成一個資料檔案,可避免同時開啟大量檔案和同時讀取大量小檔案產生的隨機讀取帶來的開銷。資訊包括在臨時檔案中的偏移量、壓縮前資料大小和壓縮後資料大小。如果當前記憶體索引大小超過1MB,則將記憶體索引寫到檔案output/spillN.out.index中。

 

Shuffle 階段 (map 端的輸出到 reduce 的輸入 )

1)maptask收集我們的map()方法輸出的kv對,放到 記憶體緩衝區

2)從記憶體緩衝區不斷溢位本地磁碟檔案,可能會溢位多個檔案 

3)多個溢位檔案會被合併成大的溢位檔案 

4)在溢位過程中,及合併的過程中,都要呼叫 partitioner 進行分割槽和針對key進行排序 

5)reducetask根據自己的分割槽號,去各個 maptask 機器上取相應的結果分割槽資料 

6)reducetask會取到同一個分割槽的來自不同maptask的結果檔案,reducetask會將這些檔案再進行合併( 歸併排序  

7)合併成大檔案後,shuffle的過程也就結束了,後面進入reducetask的邏輯運算過程(從檔案中取出一個一個的鍵值對group,呼叫使用者自定義的reduce()方法) 

3)注意Shuffle中的緩衝區大小會影響到mapreduce程式的執行效率,原則上說,緩衝區越大,磁碟io的次數越少,執行速度就越快。緩衝區的大小可以透過引數調整,引數:io.sort.mb預設100M。

 

ReduceTask 階段

1)Copy階段 ReduceTask從各個MapTask上遠端 複製一片資料 ,並針對某一片資料,如果其大小超過一定閾值,則寫到磁碟上,否則直接放到記憶體中。 

2)Merge階段 :在遠端複製資料的同時,ReduceTask啟動了兩個後臺執行緒對記憶體和磁碟上的檔案進行合併,以 防止記憶體使用過多或磁碟上檔案過多  

3)Sort階段 :按照MapReduce語義,使用者編寫 reduce()函式 輸入資料是按key進行聚集的一組資料。為了將key相同的資料聚在一起,Hadoop採用了基於排序的策略。由於各個MapTask已經實現對自己的處理結果進行了區域性排序,因此, ReduceTask只需對所有資料進行一次歸併排序即可  

4)Reduce階段 reduce()函式將計算結果寫到HDFS上


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2655146/,如需轉載,請註明出處,否則將追究法律責任。

相關文章