MapReduce工作原理


一切都是從最上方的user program開始的,user program鏈接了MapReduce庫,實現了最基本的Map函數和Reduce函數。

  1. MapReduce庫先把user program的輸入文件划分為M份(M為用戶定義),每一份通常有16MB到64MB,如圖左方所示分成了split0~4(文件塊);然后使用fork將用戶進程拷貝到集群內其它機器上。
  2. user program的副本中有一個稱為master,其余稱為worker,master是負責調度的,為空閑worker分配作業(Map作業或Reduce作業),worker數量可由用戶指定的。
  3. 被分配了Map作業的worker,開始讀取對應文件塊的輸入數據,Map作業數量是由M決定的,和split一一對應;Map作業(包含多個map函數)從輸入數據中抽取出鍵值對,每一個鍵值對都作為參數傳遞給map函數,map函數產生的中間鍵值對被緩存在內存中。
  4. 緩存的中間鍵值對會被定期寫入本地磁盤。主控進程知道Reduce的個數,比如R個(通常用戶指定)。然后主控進程通常選擇一個哈希函數作用於鍵並產生0~R-1個桶編號。Map任務輸出的每個鍵都被哈希起作用,根據哈希結果將Map的結果存放到R個本地文件中的一個(后來每個文件都會指派一個Reduce任務)。
  5. master通知分配了Reduce作業的worker它負責的分區在什么位置。當Reduce worker把所有它負責的中間鍵值對都讀過來后,先對它們進行排序,使得相同鍵的鍵值對聚集在一起。因為不同的鍵可能會映射到同一個分區也就是同一個Reduce作業(誰讓分區少呢),所以排序是必須的。
  6. reduce worker遍歷排序后的中間鍵值對,對於每個唯一的鍵,都將鍵與關聯的值傳遞給reduce函數,reduce函數產生的輸出會添加到這個分區的輸出文件中。
  7. 當所有的Map和Reduce作業都完成了,master喚醒正版的user program,MapReduce函數調用返回user program的代碼。
  8. 所有執行完畢后,MapReduce輸出放在了R個分區的輸出文件中(分別對應一個Reduce作業)。用戶通常並不需要合並這R個文件,而是將其作為輸入交給另一個MapReduce程序處理。整個過程中,輸入數據是來自底層分布式文件系統(GFS)的,中間數據是放在本地文件系統的,最終輸出數據是寫入底層分布式文件系統(GFS)的。而且我們要注意Map/Reduce作業和map/reduce函數的區別:Map作業處理一個輸入數據的分片,可能需要調用多次map函數來處理每個輸入鍵值對;Reduce作業處理一個分區的中間鍵值對,期間要對每個不同的鍵調用一次reduce函數,Reduce作業最終也對應一個輸出文件。

 

函數說明 pid_t forkvoid)

一個現有進程可以調用fork函數創建一個新進程。由fork創建的新進程被稱為子進程。fork函數被調用一次但返回兩次。兩次返回的唯一區別是子進程中返回0值而父進程中返回子進程ID。子進程是父進程的副本,它將獲得父進程數據空間、堆、棧等資源的副本。注意,子進程持有的是上述存儲空間的“副本”,這意味着父子進程間不共享這些存儲空間。


免責聲明!

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



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