MapReduce 論文公佈自 2003 MapReduce: Simplified Data Processingn。在這以前 google 天天已經有大量的數據須要處理。MapReduce 的誕生讓程序員在面對大數據量環境下只須要專一於實現業務邏輯,並在必定程度上遵循當時 MapReduce 架構下的規則便可。在當時, MapReduce 已經被用到:計算 URL 訪問頻率、 分佈式 Grep、倒排索引和分佈式排序等。程序員
MapReduce 的核心思想是:首先將須要處理的大量數據分片,而後對分片以後的內容進行處理,輸出中間內容,這個過程稱爲 Map。隨後再整合這些中間內容獲得最終結果,這個過程稱爲 Reduce。ruby
這個過程,實現起來有不少種方式,須要考慮實際業務場景,硬件資源等。在 Google,一般是某個成百上千龐大的機器集羣組成。這些機器在同時且不斷地作着 Map 和 Reduce 的工做。架構
分片: 大量的數據首先會被分紅小片,大小一般是 16M 到 64M。這個數值涉及到後面提到的數據本地化策略,數據本地化目的是爲了節省帶寬。(畢竟 03 年的時候帶寬比如今差太多)分佈式
MapReduce 任務分配: 由一個 master 程序來產生多個 worker 程序的副本跑在集羣中,這些 worker 程序一般分配 M 個 Map 任務,R 個 Reduce 任務。函數
Map 階段: Map workers 會去讀入分片以後的數據,按照用戶自定義的函數處理,而後把產生的結構爲 key-value 類型結果輸出到中間文件中。大數據
Reduce 階段一:Master 獲取階段 3 的中間文件的 index,傳給 Reduce worker。google
Reduce 階段二:Reduce worker 找到對應的中間文件,而後按照 key 進行排序,排序的目的是讓相同 key 的文件排在一塊兒。這個過程我個理解爲整合。同時,因爲把大量的文件在單獨的某個 worker 中作排序是很是耗費時間空間的,所以應該在這以前排好序,整合的時候只是一個 merge-sort 中的 merge 階段。比方說spa
# 輸入
[{k3, v1}, {k1, v2}, {k2 v1}, {k1, v3}, {k2, v2}, {k1: v1}]
# 排序
[{k1: v1}, {k1, v2}, {k1, v3}, {k2 v1}, {k2, v2}, {k3, v1}]
# 相同 key 整合
[{k1: [v1, v2, v3]}, {k2, [v1, v2]}, {k3, [v1]}]
複製代碼
Reduce 階段三: 階段 5 以後就是整合以後的內容以 key-value 爲單位傳給用戶自定義的函數。好比把 5 中的 [v1, v2, v3] 進行求和之類的操做。code
結束工做: 一般當全部的 Map worker 和 Reduce worker 都結束的時候,master 此時喚醒用戶程序(一般就是一個最開始的調用函數)。這個時候調用放就能夠收到返回。cdn
整個系統中 master 惟一,也就是說 master 若是掛了那麼外部就認爲當前集羣不可用。worker 數目較多,能夠接受必定數量的 worker 不可用。一般 master 會不斷 ping 這些 worker 同時保存他們的狀態。當某個 worker 掛掉以後,master 就認爲他的工做沒有作過,並轉交給別的 worker,這樣作的好處是每一個 worker 的工做都是原子的。當 MapReduce 執行到後面的時候,一般是有大量的 Reduce 工做須要作。這個時候 master 又可讓以前的 Map worker 轉爲 Reduce worker。