整個MapReduce Job運行流程的最初幾步是Client向JobTracker提交Job,如下圖所示,圖中第三步是將Job運行相關資源提交到JobTracker可見的文件系統上。本文將討論Client需要提交的幾個主要文件。
下圖列出了提交到staging dir上的幾個文件:首先,顯而易見的是,job.jar包含Job要執行的程序(jar文件是從Client local複製到staging dir,其他文件是直接在staging dir上生成);job.xml包含所有配置信息(所有可配置的properties)。下面將討論餘下的兩個文件。
job.split和job.splitmetainfo兩個文件存儲了有關InputSplit的信息。我們知道,Hadoop MapReduce將所有的輸入文件劃分成一個一個的InputSplit(劃分規則由InputFormat的實現類定義),且爲每一個InputSplit,JobTracker將分配一個task交給TaskTracker去執行map。那麼,在啓動Job之前,首先需要完成文件劃分,這個實際上是由Client端來執行。Client完成文件劃分後,將劃分信息寫入job.split和job.splitmetainfo,然後寫這兩個文件到staging dir。
接下來的問題是,爲什麼需要有兩個文件,它們分別存儲了什麼樣的信息?如下圖所示,job.split存儲了所有劃分出來的InputSplit,而每個InputSplit記錄如下信息:
- 該Split的類型(ClassName, mostly org.apache.hadoop.mapreduce.lib.input.FileSplit)
- 該Split所屬文件的路徑(FilePath)
- 該Split在所屬文件中的起始位置(FileOffset)
- 該Split的字節長度(Length)
- 該Split在哪些Node上是local data(Location)
- 該Split對應的InputSplit在job.split文件中的位置(SplitFileOffset)
- 該Split的字節長度(Length, the same as that in job.split)
- job.splitmetainfo提供給JobTracker讀取。比如,根據# Split,JobTracker能知道該分配多少個Task;根據Location,JobTracker能決定將該Split對應的Task分配給哪個Node去執行(優先分配到擁有該Split local data的Node)
- job.split提供給TaskTracker讀取。根據FilePath, FileOffset, Length,TaskTracker知道從哪個文件的哪個位置開始讀取要處理的Split data。
最後來看看job.split和job.splitmetainfo實際的內容,分別如下兩圖所示(該MapReduce Job運行在Local Mode)。
job.split:
job.splitmetainfo: