深入理解MapReduce原理
摘要:我們在 ofollow,noindex">《從序列到並行,從並行到分散式》 中,對序列、並行、併發和分散式進行了區分,並引出了分散式計算框架MapReduce。在這篇文章中我們會對MapReduce(Hadoop 2.0之前的版本)的概念、執行流程、工作原理進行深入探討。
1. 概念
百度百科對MapReduce的定義感覺還是比較全面的:
MapReduce是面向大資料並行處理的計算模型、框架和平臺,它隱含了以下三層含義:
1)MapReduce是一個基於叢集的高效能平行計算平臺。它允許用市場上普通的商用伺服器構成一個包含數十、數百至數千個節點的分佈和平行計算叢集。
2)MapReduce是一個平行計算與執行軟體框架。它提供了一個龐大但設計精良的平行計算軟體框架,能自動完成計算任務的並行化處理,自動劃分計算資料和計算任務,在叢集節點上自動分配和執行任務以及收集計算結果,將資料分佈儲存、資料通訊、容錯處理等平行計算涉及到的很多系統底層的複雜細節交由系統負責處理,大大減少了軟體開發人員的負擔。
3)MapReduce是一個並行程式設計模型與方法。它藉助於函式式程式設計語言Lisp的設計思想,提供了一種簡便的並行程式設計方法,用Map和Reduce兩個函式程式設計實現基本的平行計算任務,提供了抽象的操作和並行程式設計介面,以簡單方便地完成大規模資料的程式設計和計算處理。
用自己的話概況一下:
MapReduce是一個基於叢集的計算 平臺 ,是一個簡化分散式程式設計的計算 框架 ,是一個將分散式計算抽象為Map和Reduce兩個階段的程式設計 模型 。 (這句話記住了是可以用來裝逼的)
2. 執行流程
先上一張MapReduce程式的執行流程圖,我們來好好欣賞一下。

MapReduce執行原理
由圖我們可以看到, MapReduce存在以下4個獨立的實體。
1. JobClient:運行於client node,負責將MapReduce程式打成Jar包儲存到HDFS,並把Jar包的路徑提交到Jobtracker,由Jobtracker進行任務的分配和監控。
2. JobTracker:運行於name node,負責接收JobClient提交的Job,排程Job的每一個子task運行於TaskTracker上,並監控它們,如果發現有失敗的task就重新執行它。
3. TaskTracker:運行於data node,負責主動與JobTracker通訊,接收作業,並直接執行每一個任務。
4. HDFS:用來與其它實體間共享作業檔案。
各實體間通過以下過程完成一次MapReduce作業。
- JobClient通過RPC協議向JobTracker請求一個新應用的ID,用於MapReduce作業的ID
- JobTracker檢查作業的輸出說明。例如,如果沒有指定輸出目錄或目錄已存在,作業就不提交,錯誤拋回給JobClient,否則,返回新的作業ID給JobClient
- JobClient將作業所需的資源(包括作業JAR檔案、配置檔案和計算所得得輸入分片)複製到以作業ID命名的HDFS資料夾中
- JobClient通過submitApplication()提交作業
- JobTracker收到呼叫它的submitApplication()訊息後,進行任務初始化
- JobTracker讀取HDFS上的要處理的檔案,開始計算輸入分片,每一個分片對應一個TaskTracker
- TaskTracker通過心跳機制領取任務(任務的描述資訊)
- TaskTracker讀取HDFS上的作業資源(JAR包、配置檔案等)
- TaskTracker啟動一個java child子程序,用來執行具體的任務(MapperTask或ReducerTask)
- TaskTracker將Reduce結果寫入到HDFS當中
3. 工作原理
工作原理圖如下:

MapReduce工作原理圖
Map任務處理
- 讀取HDFS中的檔案。每一行解析成一個<k,v>。每一個鍵值對呼叫一次map函式
- 重寫map(),對第一步產生的<k,v>進行處理,轉換為新的<k,v>輸出
- 對輸出的key、value進行分割槽
- 對不同分割槽的資料,按照key進行排序、分組。相同key的value放到一個集合中
5.(可選) 對分組後的資料進行歸約
Reduce任務處理
多個map任務的輸出,按照不同的分割槽,通過網路複製到不同的reduce節點上
對多個map的輸出進行合併、排序。
重寫reduce函式實現自己的邏輯,對輸入的key、value處理,轉換成新的key、value輸出
把reduce的輸出儲存到檔案中