maptask工作機制如圖所示。
(1)read階段:maptask通過用戶編寫的recordreader,從輸入inputsplit中解析出一個個key/value。
(2)map階段:該節點主要是將解析出的key/value交給用戶編寫map()函數處理,并產生一系列新的key/value。
(3)collect收集階段:在用戶編寫map()函數中,當數據處理完成后,一般會調用outputcollector.collect()輸出結果。在該函數內部,它會將生成的key/value分區(調用partitioner),并寫入一個環形內存緩沖區中。
(4)spill階段:即“溢寫”,當環形緩沖區滿后,mapreduce會將數據寫到本地磁盤上,生成一個臨時文件。需要注意的是,將數據寫入本地磁盤之前,先要對數據進行一次本地排序,并在必要時對數據進行合并、壓縮等操作。
溢寫階段詳情:
- 步驟1:利用快速排序算法對緩存區內的數據進行排序,排序方式是,先按照分區編號partition進行排序,然后按照key進行排序。這樣,經過排序后,數據以分區為單位聚集在一起,且同一分區內所有數據按照key有序。
- 步驟2:按照分區編號由小到大依次將每個分區中的數據寫入任務工作目錄下的臨時文件output/spilln.out(n表示當前溢寫次數)中。如果用戶設置了combiner,則寫入文件之前,對每個分區中的數據進行一次聚集操作。
- 步驟3:將分區數據的元信息寫到內存索引數據結構spillrecord中,其中每個分區的元信息包括在臨時文件中的偏移量、壓縮前數據大小和壓縮后數據大小。如果當前內存索引大小超過1mb,則將內存索引寫到文件output/spilln.out.index中。
(5)combine階段:當所有數據處理完成后,maptask對所有臨時文件進行一次合并,以確保最終只會生成一個數據文件。
當所有數據處理完后,maptask會將所有臨時文件合并成一個大文件,并保存到文件output/file.out中,同時生成相應的索引文件output/file.out.index。
在進行文件合并過程中,maptask以分區為單位進行合并。對于某個分區,它將采用多輪遞歸合并的方式。每輪合并io.sort.factor(默認10)個文件,并將產生的文件重新加入待合并列表中,對文件排序后,重復以上過程,直到最終得到一個大文件。
讓每個maptask最終只生成一個數據文件,可避免同時打開大量文件和同時讀取大量小文件產生的隨機讀取帶來的開銷。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。如果你想了解更多相關內容請查看下面相關鏈接
原文鏈接:https://blog.csdn.net/qq_43193797/article/details/86062393