1. 程式人生 > 其它 >MapReduce 內部核心工作機制

MapReduce 內部核心工作機制

MapReduce 內部核心工作機制

  • 使用者編寫的 MapReduce 程式提交給 Yarn 叢集執行,首先 Job 客戶端會根據程式中的輸入檔案目錄去掃描所有檔案,並按照檔案切片大小(BlockSize,預設 128M)進行切片,切片完成後會將切片資訊寫入到 ArrayList 集合中,然後進行序列化,最終生成一系列切片檔案 FileSplit0、FileSplit1...,這些切片檔案儲存著切片資訊
  • AppMaster 會根據切片數量決定啟動多少個 MapTask 任務(即 Yarn Chlid 程序名),並告訴每個 MapTask 任務應該讀取哪個檔案切片
  • MapTask 任務啟動後,會根據切片資訊去相應的位置(本地系統或 HDFS )使用 TextInputFormat 元件逐行讀取資料,讀完一行資料將產生一對 kv 鍵值對(其中 k 表示讀取資料的偏移量,v 是行內容),這時將呼叫使用者定義的 Mapper 類的 map(k,v,context) 方法,將 kv 鍵值對作為引數傳遞進來,並執行使用者定義的 map 方法的資料拆分邏輯程式碼,並通過 context.write(k,v) 產生 kv 鍵值對
  • 產生的 kv 鍵值對會源源不斷的傳送到 MapOutputCollector 元件中,這個元件是一個環形結構快取區(預設 100M),這個結構設計非常精巧,目的是為了儘可能儲存更多的 kv 鍵值對,節約記憶體空間
  • MapOutputCollector 元件不斷的往環形緩衝區中寫入 kv 鍵值對,但是不可能無限制寫下去,如果寫滿了就會覆蓋之前的內容。所以,達到 80% 時就不能再寫了,這時將觸發 Spill 元件(溢位)操作
  • Spill 元件先對環形緩衝區的 kv 鍵值對進行由小到大的分割槽,預設使用 HashPartitioner 分割槽器進行分割槽,然後每個分割槽再進行 按照 Key 值的 compareTo() 方法排序
  • Spill 元件分割槽排序完成後,接著將環形緩衝區中各個分割槽的 kv 鍵值對寫入到本地磁碟檔案中。在這個過程中,MapTask 任務仍然可以繼續傳送 kv 鍵值對到環形緩衝區中,因為還有 20% 的空間可用。直到 Spill 元件將環形快取區所有 kv 鍵值對全部寫入磁碟後,環形緩衝區將釋放之前佔用的 80% 空間
  • 多個分割槽意味著將寫入多個溢位檔案到磁碟中,這時則執行合併(Merge)操作,將其合併成一個檔案,合併過程中將生成分割槽索引檔案,便有以後 ReduceTask 任務拉取自己分割槽的資料。合併後的檔案存放在 NodeManger 的 Web 伺服器的 document 路徑下。至此,MapTask 任務結束退出
  • ReduceTask 任務啟動後,首先到各個 MapTask 所在的磁碟中拷貝自己所在分割槽的 kv 鍵值對檔案,然後將這些檔案進行合併和歸併排序
  • ReduceTask 任務再呼叫使用者定義的 Reducer 類的 reduce(k,迭代器,context) 方法,這裡迭代器每迭代一次,就從檔案中讀取一對 kv 鍵值對並賦值給建立的臨時 kv 物件,再迭代一次只需要給 kv 物件重新賦值即可,不需要再建立新的 kv 物件
  • 檔案中所有 kv 鍵值對讀取完之後,通過 context.write(k,v,context) 方法將結果輸出,這時將呼叫 TextOutputFormat 元件的 LineRecordWriter 的 write(k,v) 將結果寫入到本地檔案系統或 HDFS中,寫檔案的名稱為 part-r-xxxxx,內容格式為 key \t value
  • ReduceTask 任務完成後退出

注意:MapTask 生成的資料傳輸到 ReduceTask 的過程被稱為 Shuffle(混洗)