Hadoop在大數據領域可以說是元老級別的人物,無人不知無人不曉。然鵝作爲Hadoop系列的開山之作,本文並不涉及Hadoop的安裝配置以及基礎概念,本文就利用Linux的pipe簡單解釋一下Hadoop中的MapReduce到底幹了什麼,包你一看就懂。
Hadoop有四大組件:
- HDFS:分佈式存儲系統
- MapReduce:分佈式計算系統
- YARN: hadoop 的資源調度系統
- Common: 以上三大組件的底層支撐組件,主要提供基礎工具包和 RPC 框架等
本文先來講講MapReduce的那些事,從是什麼,爲什麼以及怎麼做三個方面來講。
1 什麼是MapReduce
說起Hadoop就必須得提MapReduce,MapReduce是一種編程模型,其理論來自Google公司發表的MapReduce論文,主要應用於海量數據的並行計算。MapReduce又可以分爲map和reduce(暫時忽略中間的shuffle,partition等內容)
- Map:map有個中文釋義就是映射,是一個映射過程,把一組數據按照某種Map函數映射成新的數據。
- Reduce:reduce有個中文釋義就是歸約,是一個歸約過程,把若干組映射結果進行彙總並輸出。
聽上面的概念聽的滿頭包?放心,舉個MR界的hello world幫助理解:比如現在給你一堆學生寫的英文作文,需要讓你統計這麼多份英文作文中每個單詞出現的次數,應該怎麼做呢?你有如下選擇:
- 選擇自己默默承擔一切,加班熬夜一份一份的數
- 找幾個學生幫你一起數,Emmmm
反正如果是我,我肯定選擇後者。但是這樣就會產生一個新的問題,如果現在找到了10個學生來幫你完成這個任務,每個人負責十分之一,那麼他們十個人統計的結果最後還需要再求個並集,這又是好大一份工作量,好煩怎麼辦?這時候就可以利用MR的思想,先找幾個學生作爲報數員,他們的工作非常簡單,只需要從前往後瀏覽每篇文章,看到一個詞就讀出來這個單詞,然後有對應的計數員在那對報數員念出來的單詞進行記錄。如有一篇文章是這麼寫的:
I have a pen, I have an apple.
那麼計數員就會記下:
I 1
have 1
a 1
pen, 1
I 1
have 1
an 1
apple. 1
嗯看起來很簡單,但你要清楚這只是從一個報數員那得到的結果,現在老師找來了n個報數員,他們每個人讀完一篇文章計數員都會生成這麼一個單詞和出現次數的key/value對。因此還需要第三組同學對所有的key/value對進行處理並排序。
假如現在只有兩篇作文,另一篇作文是:
I am so sad.
計數員得到:
I 1
am 1
so 1
sad. 1
在對上面兩篇作文進行歸併並排序之後得到:
I 1
I 1
I 1
a 1
am 1
an 1
apple. 1
have 1
have 1
pen, 1
sad. 1
so 1
接下來我們只需要最後一名同學,對上面的數據進行最後的合併,即將key值相同的結果合爲一個key/value對。最後得到如下結果:
I 3
a 1
am 1
an 1
apple. 1
have 2
pen, 1
sad. 1
so 1
如此就完成了整個統計任務,上面的流程可以用下圖表示:
![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvOTgwNTc1LzE1ODczOTQwMzQxNDMtNTQ1ZGU0OWEtOWNkNi00MDU5LTgzZjctYjMxNTFjZDlmMTY2LnBuZw?x-oss-process=image/format,png#align=left&display=inline&height=430&margin=[object Object]&name=image.png&originHeight=693&originWidth=1151&size=59641&status=done&style=none&width=712)
至於每一階段的細節,本文先不介紹,只需要有個大概的理解就行。
2 爲什麼需要MapReduce
其實上面的例子已經解釋了這個問題,因爲數據多,數據存儲在多個機器上,使用MR能夠讓每種類型的Worker專注於他自己要做的簡單的事情,同時高效的解決數據多數據分步在多個主機的問題。
3 MapReduce在做什麼
上面的例子也已經解釋了這個問題,MapReduce主要可以拆分爲Map和Reduce,map從輸入讀取數據,將數據做拆分,reduce負責對具有相同key的數據進行拼裝;中間隱藏的部分可以簡單理解爲對數據進行整理,按照key的值進行排序,叫做shuffle,這幾個部分協同合作完成一個可能並不複雜但是數據量很大的任務。
4 MapReduce應用舉例
在本文中我們藉助Linux的管道模擬一下MapReduce的工作流程,首先實現一個WordCount,這裏我用python腳本做示範,準備數據文件:
I have a pen, I have an apple.
I am so sad.
mapper.py
import sys
for line in sys.stdin:
words = line.strip().split()
for word in words:
print "%s\t%s" % (word, 1)
reducer.py
import sys
cur_word = None
cur_count = 0
for line in sys.stdin:
data = line.strip().split()
if data[0] != cur_word:
if cur_word != None and cur_count != 0:
print "%s\t%s" % (cur_word, cur_count)
cur_word = data[0]
cur_count = 0
cur_count += 1
if data[0] == cur_word and cur_count != 0:
print "%s\t%s" % (cur_word, cur_count)
在Linux中執行如下命令:
cat ./data | python mapper.py | sort | python reducer.py
即可得到在第一小節我們最終得到的結果。
解釋一下 這裏需要解釋以下兩個問題:
- 爲什麼在reducer.py中要那樣寫?這是由於MapReduce的特性決定的,具有相同key的key/value對會被送給同一個reducer;而且同一個reducer可以接收多個key值得key/value對。因此需要判斷當前讀取到的鍵值對的key是否和之前一樣,如果讀取到新的key就需要將之前的統計結果寫到輸出文件中,並重置統計結果。這一塊對新人來說,可能不是很好理解。
- 爲什麼上面的命令要加上sort?這也是由MapReduce的特性決定的,送給reducer的數據就是按照key排好序的,這樣才能確保把具有相同key的鍵值對送給了同一個reducer,從而確保計算結果沒有出錯。
5 更多
本文只是對MapReduce的工作流程做了一個簡單的口語化的解釋,而且給的例子也是Hello World級別的了,實際中的MR代碼邏輯會複雜的多,比如在map端對數據做join,在reduce端對數據做join,多個MR的串聯等等,後面的文章會更加深入的介紹。