MapReduce的理解


1 什么是MapReduce?

  Map本意可以理解為地圖,映射(面向對象語言都有Map集合),這里我們可以理解為從現實世界獲得或產生映射。Reduce本意是減少的意思,這里我們可以理解為歸並前面Map產生的映射。

 

2 MapReduce的編程模型

  按照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值的集合。

 

3 MapReduce實現

  通過將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過程

 

4 例子

  假設我們需要處理一批有關天氣的數據,其格式如下: 按照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作為輸出: 
  (1950, 22) 
  (1949, 111) 
  (1937, 1) 
  (1945, 78) 


  其邏輯過程可用如下圖表示: 

 參考:

http://desert3.iteye.com/blog/865243

http://www.cnblogs.com/duguguiyu/archive/2009/02/28/1400278.html

http://www.cnblogs.com/MitiskySean/p/3320451.html

<<MapReduce: Simplied Data Processing on Large Clusters>>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM