org.apache.hadoop.mapred.JobTracker類是個獨立的程式,有自己的main函式。JobTracker是在網路環境中提交及執行MR任務的核心位置。
main方法主要程式碼有兩句:
1 //建立jobTracker物件 2 JobTracker tracker = startTracker(new JobConf()); 3 //啟動各個服務,包括JT內部一些重要的服務或者執行緒 4 tracker.offerService();
一、startTracker(new JobConf())根據配置檔案啟動JobTracker,這個方法會呼叫startTracker(conf, generateNewIdentifier())方法進行啟動操作,generateNewIdentifier()將會返回一個以節點當前時間格式化成“yyyyMMddHHmm”的字串。
startTracker函式是一個靜態函式,它呼叫JobTracker的建構函式生成一個JobTracker類的例項,建構函式主要工作是對一些重要的變數進行初始化,名為result。然後,進行了一系列初始化活動,包括啟動RPC server,啟動內建的jetty伺服器,檢查是否需要重啟JobTracker等。
初始化的重要物件包括:
1、secretManager:DelegationTokenSecretManager的例項,MR安全管理相關類;
2、aclsManager:ACLsManager的例項,作業級別和佇列級別的管理和訪問許可權控制;
3、taskScheduler:TaskScheduler的例項,排程器物件,hadoop預設的排程器是FIFO策略的JobQueueTaskScheduler;
4、interTrackerServer:Server的例項,RPC Server;
5、infoServer:HttpServer的例項,將Job、Task、TaskTracker相關資訊顯示到WEB前端,封裝的是jetty;
6、recoveryManager:RecoveryManager的例項,作業恢復管理,即JobTracker啟動時,恢復上次停止時正在執行的作業,並恢復各個任務的執行狀態;recoveryManager.checkAndAddJob(status)會檢查出那些作業需要恢復並放入Set<JobID> jobsToRecover; // set of jobs to be recovered,為後面的recoveryManager.recover()做準備;
7、jobHistoryServer:JobHistoryServer的例項,用於檢視作業歷史資訊的Server;
8、dnsToSwitchMapping:DNSToSwitchMapping的例項,用於構建叢集的網路拓撲結構,它能將節點地址(IP或者host)對映成網路位置。
二、 tracker.offerService()
1 /** 2 * Run forever 3 */ 4 public void offerService() throws InterruptedException, IOException { 5 // Prepare for recovery. This is done irrespective of the status of restart 6 // flag. 7 while (true) { 8 try { 9 recoveryManager.updateRestartCount(); 10 break; 11 } catch (IOException ioe) { 12 LOG.warn("Failed to initialize recovery manager. ", ioe); 13 // wait for some time 14 Thread.sleep(FS_ACCESS_RETRY_PERIOD); 15 LOG.warn("Retrying..."); 16 } 17 } 18 19 taskScheduler.start(); 20 21 // Start the recovery after starting the scheduler 22 try { 23 recoveryManager.recover(); 24 } catch (Throwable t) { 25 LOG.warn("Recovery manager crashed! Ignoring.", t); 26 } 27 // refresh the node list as the recovery manager might have added 28 // disallowed trackers 29 refreshHosts(); 30 //用於發現和清理死掉的TaskTracker 31 this.expireTrackersThread = new Thread(this.expireTrackers, 32 "expireTrackers"); 33 this.expireTrackersThread.start(); 34 //用於清理長時間駐留在記憶體中的已經執行完成的作業資訊 35 this.retireJobsThread = new Thread(this.retireJobs, "retireJobs"); 36 this.retireJobsThread.start(); 37 //用於發現已經被分配給某個TaskTracker但一直未彙報資訊的任務 38 expireLaunchingTaskThread.start(); 39 40 if (completedJobStatusStore.isActive()) { 41 completedJobsStoreThread = new Thread(completedJobStatusStore, 42 "completedjobsStore-housekeeper"); 43 //將已經執行完成的作業執行資訊儲存到HDFS上,並提供了一套存取這些資訊的API。 44 completedJobsStoreThread.start(); 45 } 46 47 // start the inter-tracker server once the jt is ready 48 this.interTrackerServer.start(); 49 50 synchronized (this) { 51 state = State.RUNNING; 52 } 53 LOG.info("Starting RUNNING"); 54 55 this.interTrackerServer.join(); 56 LOG.info("Stopped interTrackerServer"); 57 }
1、首先是不論重啟是什麼狀態都必須要做的recoveryManager.updateRestartCount()更新JobTracker叢集重啟次數,更新檔案${hadoop.tmp.dir}/mapred/system/jobtracker.info。該方法首先判斷如果有restartFile(就是前面說的更新檔案),就刪除tmpRestartFile(不管存在與否);如果不存在restartFile而存在tmpRestartFile,則將tmpRestartFile重新命名為restartFile;如果兩個檔案都沒有可能是第一次啟動也可能是檔案丟失了,這時就不用恢復操作了shouldRecover = false,並且建立一個restartFile寫入0;再讀出restartFile檔案的數字,並+1,建立一個tmpRestartFile將增加後的重啟次數計數器restartCount寫入這個檔案,刪除restartFile檔案,將tmpRestartFile改名為restartFile。這個重啟次數存在的目的官方說法是“The whole purpose of this api is to obtain restart counts across restarts to avoid attempt-id clashes.”
2、taskScheduler.start()是啟動排程器。預設的排程器是JobQueueTaskScheduler,其start()方法如下:
1 //JobQueueTaskScheduler類的start方法主要註冊了兩個非常重要的監聽 器: 2 //jobQueueJobInProgressListener和eagerTaskInitializationListener。 3 //前者是 JobQueueJobInProgressListener類的一個例項,該類以先進先出的方式維持一個JobInProgress的佇列, 4 //並且監聽各 個JobInProgress例項在生命週期中的變化;後者是EagerTaskInitializationListener類的一個例項, 5 //該類不斷監 聽jobInitQueue,一旦發現有新的job被提交(即有新的JobInProgress例項被加入), 6 //則立即呼叫該例項的initTasks方 法,對job進行初始化。 7 @Override 8 public synchronized void start() throws IOException { 9 //呼叫TaskScheduler.start()方法,實際上沒有做任何事情 10 super.start(); 11 //註冊一個JobInProgressListerner監聽器 12 taskTrackerManager.addJobInProgressListener(jobQueueJobInProgressListener); 13 eagerTaskInitializationListener.setTaskTrackerManager(taskTrackerManager); 14 eagerTaskInitializationListener.start(); 15 taskTrackerManager.addJobInProgressListener( 16 eagerTaskInitializationListener); 17 }
taskTrackerManager其實就是JobTracker。eagerTaskInitializationListener.start()會啟動一個執行緒始終監控List<JobInProgress> jobInitQueue一旦發現裡面有新的JobInProgress就構造一個InitJob執行緒放入threadPool執行緒池中執行,該執行緒通過JobTracker.initJob(JobInProgress job)對Job進行初始化。然後向JobTracker註冊eagerTaskInitializationListener。
3、recoveryManager.recover()。JobTracker節點由於意外情況而當機的話,那麼可能有一部分Job正在執行,也有一部分Job被使用者成功提交了可還沒有開始被排程執行,那麼當我們重啟JobTracker節點的時候就需要恢復或者重做這些還沒有完成的Job。這裡要說的是RecoveryManager啟動對未完成Job的恢復是在JobTracker節點的主執行緒中完成的,而且是在JobTracker節點的所有後臺執行緒啟動之前,這個呼叫必須要在所有的未完成的Job被完成之後才返回。也就是說,JobTracker的作業恢復管理器在恢復作業的處理過程中,JobTracker節點不會接受客戶端的任何請求,也不接受TaskTracker的任何請求。這個比較複雜以後再講解。
4、refreshHosts()方法會先重新載入mapred.hosts和mapred.hosts.exclude指定的檔案中主機資訊到相應的Set中;然後從taskTrackers中找出沒在mapred.hosts中但在mapred.hosts.exclude中的taskTracker從相關的資料結構中刪除此taskTracker。節點均以mapred.hosts和mapred.hosts.exclude中的為準。
5、啟動一個ExpireTrackers執行緒會監控trackerExpiryQueue一旦裡面TaskTracker有超過10分鐘沒有心跳的,JobTracker就認為它死了,將其從相關的資料結構trackerToMarkedTasksMap、trackerToJobsToCleanup、trackerToTasksToCleanup以及trackerToTaskMap刪除。這在lostTaskTracker(TaskTracker taskTracker)方法中進行。
6、啟動一個RetireJobs執行緒,會將jobs中的完成的job儲存一定時長後,從taskidToTrackerMap、trackerToTaskMap、taskidToTIPMap、jobs、userToJobsMap(每個使用者完成的job數要>100)資料結構中刪除。
7、啟動一個ExpireLaunchingTasks執行緒,如果一個TaskAttemptID超過10分鐘沒有回報資訊,則JobTracker認為這個task已經失敗,從launchingTasks刪除相關資訊,並將此task狀態標註為FAILED。
8、啟動一個CompletedJobStatusStore執行緒,預設"mapred.job.tracker.persist.jobstatus.active"是false表示不啟動這個執行緒,如果啟用則需要指定儲存時間"mapred.job.tracker.persist.jobstatus.hours"(預設是0,不儲存)和儲存路徑"mapred.job.tracker.persist.jobstatus.dir"(預設是/jobtracker/jobsInfo)。如果不啟用該執行緒則所有的作業執行資訊全部在記憶體中,且隨著時間及執行任務的增多早期的作業資訊會被刪除。
這樣JobTracker就啟動了。。。。就等著Client提交Job。。。
參考:1、董西成,《Hadoop技術內幕:深入解析MapReduce架構設計與實現原理》
2、http://blog.csdn.net/xhh198781/article/details/7354257