MapReduce之MapTask工作機制

1. 階段定義

MapTask:map—–>sort
map:Mapper.map()中將輸出的key-value寫出之前
sort:Mapper.map()中將輸出的key-value寫出之後

2. MapTask工作機制

  1. Read階段
    MapTask通過用戶編寫的RecordReader,從輸入InputSplit中解析出一個個key/value

  2. Map階段
    該節點主要是將解析出的key/value交給用戶編寫map()函數處理,併產生一系列新的key/value。

  3. Collect收集階段
    在用戶編寫map()函數中,當數據處理完成後,一般會調用OutputCollector.collect()輸出結果。在該函數內部,它會將生成的key/value分區(調用Partitioner),並寫入一個記憶體緩衝區中,並且會被Partitioner計算一個分區號,按照先後順序分配index下標

  4. Spill階段

  • 即「溢寫」,在此階段有兩個重要執行緒。收集執行緒負責向緩衝區收集數據,緩衝區初始值為100M,當使用到80%閾值,喚醒溢寫執行緒,溢寫執行緒會將緩衝區已經收集的數據溢寫到磁碟。

  • 在溢寫前,會對緩衝區中的數據進行排序(快速排序),在排序時,只通過比較key進行排序,只改變index的位置,不交換數據的位置

  • 排序後,按照分區,依次將數據寫入到磁碟的臨時文件的若干分區中

  • 每次溢寫都會生成一個臨時文件,當所有的數據都溢寫完成之後,會將所有的臨時文件片段合併為一個總的文件

  1. Combine階段
  • 在合併時,將所有的臨時文件的相同分區的數據,進行合併,合併後再對所有的數據進行排序(歸併排序)

  • 最終生成一個結果文件(output/file.out),同時生成相應的索引文件output/file.out.index,這個文件分為若干分區,每個分區的數據已經按照key進行了排序,等待reduceTask的shuffle執行緒來拷貝數據!

溢寫階段詳情:

  • 步驟1:利用快速排序演算法對快取區內的數據進行排序,排序方式是,先按照分區編號Partition進行排序,然後按照key進行排序。這樣,經過排序後,數據以分區為單位聚集在一起,且同一分區內所有數據按照key有序。

  • 步驟2:按照分區編號由小到大依次將每個分區中的數據寫入任務工作目錄下的臨時文件output/spillN.out(N表示當前溢寫次數)中。如果用戶設置了Combiner,則寫入文件之前,對每個分區中的數據進行一次聚集操作。

  • 步驟3:將分區數據的元資訊寫到記憶體索引數據結構SpillRecord中,其中每個分區的元資訊包括在臨時文件中的偏移量、壓縮前數據大小和壓縮後數據大小。如果當前記憶體索引大小超過1MB,則將記憶體索引寫到文件output/spillN.out.index中。

Tags: