在MRAppMaster中,记录日志是由服务JobHistoryEventHandler完成的,而作业恢复是由服务RecoveryService完成的。

同MRv1一样,MRv2也会对一些关键的时间记录日志,这主要有两个作用:(1)方便用户查看历史作业运行信息 (2)作业因故障重新启动后,可根据日志信息恢复之前已经运行完成的任务,以减少重新计算代价。

MRAppMaster采用的日志格式与MRv1一样,但有两个小的改动:

  • 实现方式不同。MRv1采用了同步记录日志的方式,也就是说,每发生一个行为,会记录一次日志,然后才可以执行下面的代码。由于YARN引入了基于事件的异步编程模型,因此,MRAppMaster也采用了异步方式记录日志。
  • 存储位置不同。尽管MRv1允许用户将作业日志存放到HDFS上,但默认是存储到本地的,MRAppMaster则不同,它直接将日志写到HDFS上,这样,当MRAppMaster失败后,另一个MRAppMaster启动时,可直接读取HDFS中上一个作业产生的日志,以恢复已经运行完成的任务。

当前MRAppMaster记录的日志事件包括以下几类:

作业恢复的过程是重新解析作业日志,以恢复各个任务运行状态的过程(重做日志),这是由RecoveryService完成的。如果用户将yarn.app.mapreduce.am.job.recovery.enable参数置为true(默认就是true),则MRAppMaster运行作业之前,首先会检查这是否是第一次运行该作业,如果不是,则从HDFS上读取上次运行的作业日志,并恢复作业的运行状态,然后才会按照正常流程执行。相关代码如下(在MRAppMaster类中):

public void init(final Configuration conf) {
boolean recoveryEnabled = conf.getBoolean(
        MRJobConfig.MR_AM_JOB_RECOVERY_ENABLE, true);
      boolean recoverySupportedByCommitter = committer.isRecoverySupported();
      if (recoveryEnabled && recoverySupportedByCommitter
        && appAttemptID.getAttemptId() > 1) {
      LOG.info("Recovery is enabled. "
          + "Will try to recover from previous life on best effort basis.");
      recoveryServ = createRecoveryService(context);
      addIfService(recoveryServ);
      dispatcher = recoveryServ.getDispatcher();
      clock = recoveryServ.getClock();
      inRecovery = true;
}
}
public void start() {
 if (inRecovery) {
  completedTasksFromPreviousRun = recoveryServ.getCompletedTasks();
  amInfos = recoveryServ.getAMInfos();
 }
……
}

原创文章,转载请注明: 转载自董的博客

本文链接地址: YARN/MRv2 MRAppMaster深入剖析—作业恢复

微信公众号:hadoop-123,专注于大数据技术分享,欢迎加入!

说点什么

avatar
  Subscribe  
提醒