map本意可以了解為地圖,映射(面向對象語言都有map集合),這裡我們可以了解為從現實世界獲得或産生映射。reduce本意是減少的意思,這裡我們可以了解為歸并前面map産生的映射。
按照google的mapreduce論文所說的,mapreduce的程式設計模型的原理是:利用一個輸入key/value對集合來産生一個輸出的key/value對集合。mapreduce庫的使用者用兩個函數表達這個計算:map和reduce。使用者自定義的map函數接受一個輸入的key/value對值,然後産生一個中間key/value對值的集合。mapreduce庫把所有具有相同中間key值的中間value值集合在一起後傳遞給reduce函數。使用者自定義的reduce函數接受一個中間key的值和相關的一個value值的集合。reduce函數合并這些value值,形成一個較小的value值的集合。
通過将map調用的輸入資料自動分割為m個資料片段的集合,map調用被分布到多台機器上執行。輸入的資料片段能夠在不同的機器上并行處理。使用分區函數将map調用産生的中間key值分成r個不同分區(例如,hash(key) mod r),reduce調用也被分布到多台機器上執行。分區數量(r)和分區函數由使用者來指定。
mapreduce實作的大概過程如下:
1.使用者程式首先調用的mapreduce庫将輸入檔案分成m個資料片度,每個資料片段的大小一般從16mb到64mb(可以通過可選的參數來控制每個資料片段的大小)。然後使用者程式在叢集中建立大量的程式副本。
2.這些程式副本中的有一個特殊的程式master。副本中其它的程式都是worker程式,由master配置設定任務。有m個map任務和r個reduce任務将被配置設定,master将一個map任務或reduce任務配置設定給一個空閑的worker。
3.被配置設定了map任務的worker程式讀取相關的輸入資料片段,從輸入的資料片段中解析出key/value對,然後把key/value對傳遞給使用者自定義的map函數,由map函數生成并輸出的中間key/value對,并緩存在記憶體中。
4.緩存中的key/value對通過分區函數分成r個區域,之後周期性的寫入到本地磁盤上,會産生r個臨時檔案。緩存的key/value對在本地磁盤上的存儲位置将被回傳給master,由master負責把這些存儲位置再傳送給reduce worker。
5.當reduce worker程式接收到master程式發來的資料存儲位置資訊後,使用rpc從map worker所在主機的磁盤上讀取這些緩存資料。當reduce worker讀取了所有的中間資料(這個時候所有的map任務都執行完了)後,通過對key進行排序後使得具有相同key值的資料聚合在一起。由于許多不同的key值會映射到相同的reduce任務上,是以必須進行排序。如果中間資料太大無法在記憶體中完成排序,那麼就要在外部進行排序。
6.reduce worker程式周遊排序後的中間資料,對于每一個唯一的中間key值,reduce worker程式将這個key值和它相關的中間value值的集合(這個集合是由reduce worker産生的,它存放的是同一個key對應的value值)傳遞給使用者自定義的reduce函數。reduce函數的輸出被追加到所屬分區的輸出檔案。
上面過程中的排序很容易了解,關鍵是分區,這一步最終決定該鍵值對未來會交給哪個reduce任務,如統計單詞出現的次數可以用前面說的hash(key) mod r來分區,如果是對資料進行排序則應該根據key的分布進行分區。
圖1 mapreduce過程
假設我們需要處理一批有關天氣的資料,其格式如下: 按照ascii碼存儲,每行一條記錄,每一行字元從0開始計數,第15個到第18個字元為年,第25個到第29個字元為溫度,其中第25位是符号+/-,現在需要統計出每年的最高溫度。
0067011990999991950051507+0000+
0043011990999991950051512+0022+
0043011990999991950051518-0011+
0043012650999991949032412+0111+
0043012650999991949032418+0078+
0067011990999991937051507+0001+
0043011990999991937051512-0002+
0043011990999991945051518+0001+
0043012650999991945032412+0002+
0043012650999991945032418+0078+
mapreduce主要包括兩個步驟:map和reduce 每一步都有key/value對作為輸入和輸出:
map階段的key/value對的格式是由輸入的格式所決定的,如果是預設的textinputformat,則每行作為一個記錄程序處理,其中key為此行的開頭相對于檔案的起始位置,value就是此行的字元文本,map階段的輸出的key/value對的格式必須同reduce階段的輸入key/value對的格式相對應
對于上面的例子,在map過程,輸入的key-value對如下:
(0 ,0067011990999991950051507+0000+)
(1 ,0043011990999991950051512+0022+)
(2 ,0043011990999991950051518-0011+)
(3 ,0043012650999991949032412+0111+)
(4 ,0043012650999991949032418+0078+)
(5 ,0067011990999991937051507+0001+)
(6 ,0043011990999991937051512-0002+)
(7 ,0043011990999991945051518+0001+)
(8 ,0043012650999991945032412+0002+)
(9 ,0043012650999991945032418+0078+)
将上面的資料作為使用者編寫的map函數的輸入,通過對每一行字元串的解析,得到年/溫度的key/value對作為輸出:
(1950, 0)
(1950, 22)
(1950, -11)
(1949, 111)
(1949, 78)
(1937, 1)
(1937, -2)
(1945, 1)
(1945, 2)
(1945, 78)
在reduce過程,将map過程中的輸出,按照相同的key将value放到同一個清單中作為使用者寫的reduce函數的輸入
(1950, [0, 22, –11])
(1949, [111, 78])
(1937, [1, -2])
(1945, [1, 2, 78])
在reduce過程中,在清單中選擇出最大的溫度,将年/最大溫度的key/value作為輸出:
其邏輯過程可用如下圖表示:
參考:
<a target="_blank" href="http://desert3.iteye.com/blog/865243">http://desert3.iteye.com/blog/865243</a>
<a target="_blank" href="http://www.cnblogs.com/duguguiyu/archive/2009/02/28/1400278.html">http://www.cnblogs.com/duguguiyu/archive/2009/02/28/1400278.html</a>
<a target="_blank" href="http://www.cnblogs.com/mitiskysean/p/3320451.html">http://www.cnblogs.com/mitiskysean/p/3320451.html</a>