1、 文件上傳
DFSClient向JobTracker提交任務之前,會將任務運行所需要的文件放入HDFS,從而可被JobTracker和TaskTracker得到:一般有執行文件,配置文件,input數據等
當Map-Reduce程序停在JobTracker.submitJob函數中的時候,讓我們查看HDFS中有如下的變化:
bin/hadoop fs -ls /data/hadoopdir/tmp/mapred/system
其中多了一個文件夾job_201011202025_0001,這是當前運行的Job的ID,在這個文件夾中有我們傳上去的文件。(路徑可以設置,這個路徑是用來保存客戶端傳上來的臨時文件的)
jobtracker根據用戶提交的信息,得到jobid,用戶組及判斷權限,另外將job的信息寫到hdfs上,以便tasktracker能夠訪問。
2、 任務拆分
在JobTracker.submitJob的函數中,會讀取這些上傳到HDFS的文件,從而將Job拆分成Map Task和Reduce Task。
然後再調用addJob()方法,方法中會將job加入到jobs隊列中,job隊列採用了map數據結構,
Map<JobID,JobInProgress> jobs = new TreeMap<JobID, JobInProgress>();
可以很方便的通過jobid找到該job相應的JobInProgress對象。同時也會加入到JobInProgressListener類中,此類主要是用來監聽job的類。完成後,最後將返回job的狀態。
當 TaskTracker通過heartbeat向JobTracker請求一個Map Task或者Reduce Task來運行。
3、 任務本地化
tasktracker開始去獲取一個task,獲取task是通過FairScheduler實現的。FairScheduler是hadoop中的作業公平調度器,主要是解決當TT發送心跳告訴JT當前的空閒slots時,希望JT分配給TT相應多個task,讓TT去執行這些task。所以JT就需要一個調度器來對作業進行調度,選擇出作業,然後將作業的task分配TT去執行。而hadoop中的task可以分爲map,reduce,jobsetup,jobcleanup,taskcleanup這五種task。更多細節請參見:FairScheduler(公平調度器)的源碼閱讀
當TaskTracker得到一個Task的時候,它會調用TaskTracker.localizeJob將job運行的三個文件從HDFS中拷貝到本地文件夾,然後調用TaskInProgress.localizeTask創建Task運行的本地工作目錄。
程序停在做完localizeTask後,tasktracker上的/data/hadoopdir/tmp/mapred/local/taskTracker/jobcache下多了一個文件夾job_201011202025_00014、 執行
接下來要創建Child JVM來執行Task5、 reduce
Reduce Task包括三個過程:copy,sort,reduce拷貝過程即將所有的map結果複製到reduce task的本地
在拷貝的過程中,有一個背後的線程會對已經拷貝到本地的map.out進行預先的合併,形成map.merged文件,合併的規則是按照 io.sort.factor來進行合併,對於我們的配置就是兩兩合併,下面我們看到的就是map_2.out和map_3.out合併成 map_3.out.merged,在另外兩個還沒有合併的時候,拷貝過程結束了,則背後的合併進程也就結束了。
reduce的過程就是循環調用reducer的reduce函數,將結果輸出到HDFS中。