Job的任務執行流程之JobCleanup階段

    JobTracker節點給TaskTracker節點分配作業任務時是有優先級順序的,JobTracker節點總是優先分配一個作業的輔助任務,然後在分配作業的正式任務。其中,作業的輔助任務包括:JobSetup、JobCleanup、TaskCleanup三種類型的任務,正式任務包括:Map、Reduce兩種任務。當JobTracker節點爲一個TaskTracker節點分配了輔助任務的時候就不會爲它在分配正式任務了,而給TaskTracker分配的輔助任務中只能有一個任務。這裏就有一個問題了,只分配一個輔助任務,那麼到底優先分配一個作業的哪種類型的任務呢?JobTracker節點對輔助任務的分配是以作業爲單位的,而不是以任務類型爲單位的(請好好考慮此處的表述),這種優先級的順序如下:

1.Map類型的JobCleanup任務
2.Map類型的TaskCleanup任務
3.Map類型的JobSetup任務
4.Reduce類型的JobCleanup任務
5.Reduce類型的TaskCleanup任務
6.Reduce類型的JobSetup任務

JobSetup類型的任務在前面已經詳細的闡述過了,所以在本文,筆者將主要講述作業的JobCleanup任務。當一個作業完成時(成功、失敗、kill),JobTracker節點就會調度這個任務主要來結束作業。

     分配一個作業的JobCleanup任務的過程很簡單,它的源代碼如下:

public Task obtainJobCleanupTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts, boolean isMapSlot) throws IOException {
    if(!tasksInited.get()) {
      return null;
    }
    
    //判斷此時能夠運執行JobCleanup任務
    synchronized(this) {
      if (!canLaunchJobCleanupTask()) {
        return null;
      }
      
      String taskTracker = tts.getTrackerName();
      // Update the last-known clusterSize
      this.clusterSize = clusterSize;

      //判斷此時能否在該TaskTracker節點上運行JobCleanup任務
      if (!shouldRunOnTaskTracker(taskTracker)) {
        return null;
      }
      
      List<TaskInProgress> cleanupTaskList = new ArrayList<TaskInProgress>();
      if (isMapSlot) {
        cleanupTaskList.add(cleanup[0]);
      } else {
        cleanupTaskList.add(cleanup[1]);
      }
      TaskInProgress tip = findTaskFromList(cleanupTaskList,tts, numUniqueHosts, false);
      if (tip == null) {
        return null;
      }
      
      // Now launch the cleanupTask
      Task result = tip.getTaskToRun(tts.getTrackerName());
      if (result != null) {
        addRunningTaskToTIP(tip, result.getTaskID(), tts, true);
      }
      
      return result;
    }
     在調度一個作業的JobCleanup任務的過程中,首先需要判斷此時是否能夠運行該任務,也即是它需要滿足一定的條件,只要滿足下列三個條件中的任何一個均可,這三個條件是:

1.作業失敗了;

2.作業被kill掉了;

3.同時滿足下列四個子條件:

   a).作業的狀態爲:RUNNING或者PREP

   b).該JobCleanup任務沒有正在運行同時JobSetup任務完成了;

   c).成功完成的Map任務數量與徹底失敗的Map任務數量之和等於作業總的Map任務數;

   d).成功完成的Reduce任務數量與徹底失敗的Reduce任務數量之和等於作業總的Reduce任務數;

從上面的源代碼可以看出,一個作業有兩個JobCleanup類型的任務,一個是Map型的,一個是Reduce型的,不過,他們完成的功能是一摸一樣的,所以是需要調度這兩個任務中的一個即可。另外,它同JobSetup、Reduce任務一樣,在任何時刻,同時只能有一個實例在TaskTracker節點上執行。

     TaskTracker節點接收到JobCleanup類型的任務之後,對其本地化及調度方法同JobSetup任務等是一樣的,因爲他們都屬於Map/Reduce任務,所以都需要JVM實例來完成。JVM實例對任務的執行很簡單,這個作業級別的cleanup操作依賴於該作業的輸出提交器Outputcommitter,即主要調用它的cleanupJob()方法。對於hadoop內部默認的輸出提交其實現FileOutputCommitter,它的cleanupJob()方法主要負責刪除該作業在執行過程中創建的一些臨時文件及路徑。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章