jobtracker自身启动与FIFO 调度器的工作过程

本文详细探讨了JobTracker自身main函数的工作机制,包括如何启动JobTracker实例、配置初始化过程,以及任务调度器的启动和初始化,特别是阐述了JobTracker在接收到作业提交后如何将其加入队列并进行初始化的整个流程。通过分析startTracker()和offerService()函数,揭示了JobTracker如何管理和调度作业执行的内部机制。
  1. jobtracker自身的main函数如下:
  2.  1 public static void main(String argv[]
     2                           ) throws IOException, InterruptedException {
     3     StringUtils.startupShutdownMessage(JobTracker.class, argv, LOG);
     4     
     5     try {
     6       if(argv.length == 0) {
     7         JobTracker tracker = startTracker(new JobConf());
     8         tracker.offerService();
     9       }
    10       else {
    11         if ("-dumpConfiguration".equals(argv[0]) && argv.length == 1) {
    12           dumpConfiguration(new PrintWriter(System.out));
    13         }
    14         else {
    15           System.out.println("usage: JobTracker [-dumpConfiguration]");
    16           System.exit(-1);
    17         }
    18       }
    19     } catch (Throwable e) {
    20       LOG.fatal(StringUtils.stringifyException(e));
    21       System.exit(-1);
    22     }
    23   }
    View Code
  3. 主要代码:
  4. JobTracker tracker = startTracker(new JobConf());
            tracker.offerService();
  5. startTracker()中主要代码如下://创建一个jobTracker对象,并设置调度器
  6. result = new JobTracker(conf, identifier);
            result.taskScheduler.setTaskTrackerManager(result);
  7. offerService()函数中主要的代码:taskScheduler.start();//通过taskScheduler的start方法来启动任务调度器,之后任务调度器就开始调度任务来交给jobTracker执行。当jobClient提交一个job后,jobtracker就通过jobadded(job)方法将提交的job加入job队列中,再进一步初始化,具体参照:jobtracker对提交作业的初始化
  8. 其中taskScheduler.start()方法中FIFO 调度器代码如下:
  9.  public synchronized void start() throws IOException {
        super.start();
        taskTrackerManager.addJobInProgressListener(jobQueueJobInProgressListener);//将JobQueueJobInProgressListener加入到jobTracker中的jobInProgressListeners,taskTrackerManager在JobTracker的刚创建的时候就已经设置成jobTracker了,该行就是把实现了JobInProgressListener类的jobQueueJobInProgressListener加入到jobInProgressListeners中,而JobInProgressListener中有一个Map<JobSchedulingInfo, JobInProgress> jobQueue变量,用以存储所有的作业。因为jobQueueJobInProgressListener是被实例化了的,所有存在,实例化是在新建jobTracker对象时设置taskScheduler中完成。语句在jobQueueTaskScheduler的构造函数中:
  10. public JobQueueTaskScheduler() {
        this.jobQueueJobInProgressListener = new JobQueueJobInProgressListener();
      }

  11.     eagerTaskInitializationListener.setTaskTrackerManager(taskTrackerManager);
        eagerTaskInitializationListener.start();
        taskTrackerManager.addJobInProgressListener(
            eagerTaskInitializationListener);  }
  • //eagerTaskInitializationListener实例化,在QueueTaskScheduler中的Setconf()对象中
    1 public synchronized void setConf(Configuration conf) {
    2     super.setConf(conf);
    3     padFraction = conf.getFloat("mapred.jobtracker.taskalloc.capacitypad", 
    4                                  0.01f);
    5     this.eagerTaskInitializationListener =
    6       new EagerTaskInitializationListener(conf);
    7   }
    View Code

    而Setconf()函数是在JobTracker实例化中设置Taskscheduler的时候执行的。代码如下:

  • 1 Class<? extends TaskScheduler> schedulerClass
    2       = conf.getClass("mapred.jobtracker.taskScheduler",
    3           JobQueueTaskScheduler.class, TaskScheduler.class);
    4     taskScheduler = (TaskScheduler) ReflectionUtils.newInstance(schedulerClass, conf);
    View Code

    ReflectionUtils.newInstance(schedulerClass, conf)中的代码如下:

  •  1 public static <T> T newInstance(Class<T> theClass, Configuration conf) {
     2     T result;
     3     try {
     4       Constructor<T> meth = (Constructor<T>) CONSTRUCTOR_CACHE.get(theClass);
     5       if (meth == null) {
     6         meth = theClass.getDeclaredConstructor(EMPTY_ARRAY);
     7         meth.setAccessible(true);
     8         CONSTRUCTOR_CACHE.put(theClass, meth);
     9       }
    10       result = meth.newInstance();//产生一个TaskScheduler实例
    11     } catch (Exception e) {
    12       throw new RuntimeException(e);
    13     }
    14     setConf(result, conf);//执行setConf()方法
    15     return result;
    16   }
    View Code

    而ReflectionUtils类中的SetConf()方法如下:

  • 1 public static void setConf(Object theObject, Configuration conf) {
    2     if (conf != null) {
    3       if (theObject instanceof Configurable) {
    4         ((Configurable) theObject).setConf(conf);//TaskScheduler实现类Configurable接口,所以其执行的SetConf()方法是JobQueueTaskScheduler中的SetConf()方法
    5       }
    6       setJobConf(theObject, conf);
    7     }
    8   }
    View Code

     

  • (1)则eagerTaskInitializationListener.start()方法完成的就是:public void start() throws IOException {
        this.jobInitManagerThread = new Thread(jobInitManager, "jobInitManager");//产生一个JobInitManager类的线程。
        jobInitManagerThread.setDaemon(true);//将该线程设置为守护线程
        this.jobInitManagerThread.start();
      }
  • JobInitManager的Run()方法如下: class JobInitManager implements Runnable {
        public void run() {
          JobInProgress job = null;
          while (true) {
            try {
              synchronized (jobInitQueue) {
                while (jobInitQueue.isEmpty()) {
                  jobInitQueue.wait();//当初始化队列为空时,一直等待
                }
                job = jobInitQueue.remove(0);//依次移出队列中的对象
              }
              threadPool.execute(new InitJob(job));//对Job进行初始化,而InitJob()为一个线程class InitJob implements Runnable {
        private JobInProgress job; public InitJob(JobInProgress job) {   this.job = job; } public void run() { ttm.initJob(job); } }其最后调用的是JobTracker中的InitJob(Job)方法,初始化该Job的所有Tasks等。
            } catch (InterruptedException t) {
              LOG.info("JobInitManagerThread interrupted.");
              break;
            }
          }
          LOG.info("Shutting down thread pool");
          threadPool.shutdownNow();
        }
      }
  • (2)则其对象就会加入到JobTracker中的JobInProgressListeners中,此时JobInProgressListeners有两个对象,第一个是JobQueueInProgressListener当JobTracker中的Addjob()方法时,其JobAdded(Job)方法是JobQueueJobInProgressListener中的方法,将Job加入到调度队列中:public void jobAdded(JobInProgress job) {
        jobQueue.put(new JobSchedulingInfo(job.getStatus()), job);
      }
    第二个对象是eagerTaskInitializationListener,则其调用的是EagerTaskInitializationListener类中Jobadded(Job)方法:public void jobAdded(JobInProgress job) {
        synchronized (jobInitQueue) {
          jobInitQueue.add(job);
          resortInitQueue();
          jobInitQueue.notifyAll();
        }

      }
  • (3)之前所说的FairScheduler,CapacityScheduler没有对应的eagerTaskInitializationListener类,则在其对应的jobListener,JobQueuesManager类中必包含了初始化的过程,即哪里一定调用了JobTracker中的InitJob方法

转载于:https://www.cnblogs.com/cxtblogs/p/5039058.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值