YARN源码剖析(二):RM启动过程

org.apache.hadoop.yarn.server.resourcemanager.ResourceManager类main()分析

public static void main(String argv[]) {
    //为主线程注册一个UncaughtException处理器,设置在线程因未捕获异常而突
    //然终止时调用的默认处理程序
    Thread.setDefaultUncaughtExceptionHandler(new YarnUncaughtExceptionHandler());
    //server启动和终止是打印相应的日志(终止日志打印是通过addShutdownHook来完成的)
    StringUtils.startupShutdownMessage(ResourceManager.class, argv, LOG);
    try {
      //加载配置文件:core-default.xml,core-site.xml,yarn-default.xml,yarn-site.xml
      Configuration conf = new YarnConfiguration();
      GenericOptionsParser hParser = new GenericOptionsParser(conf, argv);
      argv = hParser.getRemainingArgs();
      // If -format-state-store, then delete RMStateStore; else startup normally TODO:实现分析
      if (argv.length == 1 && argv[0].equals("-format-state-store")) {
        deleteRMStateStore(conf);
      } else {
        //构造RM对象,
        ResourceManager resourceManager = new ResourceManager();
        //添加一个shutdownHook,用来停止服务的所有资源
        ShutdownHookManager.get().addShutdownHook(
          new CompositeServiceShutdownHook(resourceManager),
          SHUTDOWN_HOOK_PRIORITY);
        //RM初始化
        resourceManager.init(conf);
        //RM启动
        resourceManager.start();
      }
    } catch (Throwable t) {
      LOG.fatal("Error starting ResourceManager", t);
      System.exit(-1);
    }
  }

RM初始化

public void init(Configuration conf) {
    if (conf == null) {
      throw new ServiceStateException("Cannot initialize service "
                                      + getName() + ": null configuration");
    }
    if (isInState(STATE.INITED)) {  //如果当前已经初始化完了则返回
      return;
    }
    synchronized (stateChangeLock) {   
      //相当于对服务做一次校验,确保服务初始化成功
      if (enterState(STATE.INITED) != STATE.INITED) { 
        setConfig(conf);
        try {
          serviceInit(config);
          if (isInState(STATE.INITED)) {
            //if the service ended up here during init,
            //notify the listeners
            notifyListeners();
          }
        } catch (Exception e) {
          noteFailure(e);
          ServiceOperations.stopQuietly(LOG, this);
          throw ServiceStateException.convert(e);
        }
      }
    }
  }
@Override
  protected void serviceInit(Configuration conf) throws Exception {
    this.conf = conf;
    this.rmContext = new RMContextImpl();
    
    this.configurationProvider =
        ConfigurationProviderFactory.getConfigurationProvider(conf);
    this.configurationProvider.init(this.conf);
    rmContext.setConfigurationProvider(configurationProvider);

    // load core-site.xml
    InputStream coreSiteXMLInputStream =
        this.configurationProvider.getConfigurationInputStream(this.conf,
            YarnConfiguration.CORE_SITE_CONFIGURATION_FILE);
    if (coreSiteXMLInputStream != null) {
      this.conf.addResource(coreSiteXMLInputStream);
    }

    // Do refreshUserToGroupsMappings with loaded core-site.xml
    Groups.getUserToGroupsMappingServiceWithLoadedConfiguration(this.conf)
        .refresh();

    // Do refreshSuperUserGroupsConfiguration with loaded core-site.xml
    // Or use RM specific configurations to overwrite the common ones first
    // if they exist
    RMServerUtils.processRMProxyUsersConf(conf);
    ProxyUsers.refreshSuperUserGroupsConfiguration(this.conf);

    // load yarn-site.xml
    InputStream yarnSiteXMLInputStream =
        this.configurationProvider.getConfigurationInputStream(this.conf,
            YarnConfiguration.YARN_SITE_CONFIGURATION_FILE);
    if (yarnSiteXMLInputStream != null) {
      this.conf.addResource(yarnSiteXMLInputStream);
    }

    validateConfigs(this.conf);
    
    // Set HA configuration should be done before login
    this.rmContext.setHAEnabled(HAUtil.isHAEnabled(this.conf));
    if (this.rmContext.isHAEnabled()) {
      HAUtil.verifyAndSetConfiguration(this.conf);
    }
    
    // Set UGI and do login
    // If security is enabled, use login user
    // If security is not enabled, use current user
    this.rmLoginUGI = UserGroupInformation.getCurrentUser();
    try {
      doSecureLogin();
    } catch(IOException ie) {
      throw new YarnRuntimeException("Failed to login", ie);
    }
    //前面的代码关键就做了初始化配置文件,读取配置文件,设置配置文件上下文这类的事情,就不多做分析了

    // register the handlers for all AlwaysOn services using setupDispatcher().
    // 注册了一个调度器,用于内部事件调度处理:new AsyncDispatcher(),
    //并且为其注册一个事件类型-handler元素
    //<RMFatalEventType.class,RMFatalEventDispatcher>
    rmDispatcher = setupDispatcher();
    //rmDispatcher也是一个service,将其添加到RM的serviceList成员中
    addIfService(rmDispatcher);
    rmContext.setDispatcher(rmDispatcher);

    adminService = createAdminService();
    addService(adminService);
    rmContext.setRMAdminService(adminService);
    
    rmContext.setYarnConfiguration(conf);
    
    //
    createAndInitActiveServices();

    webAppAddress = WebAppUtils.getWebAppBindURL(this.conf,
                      YarnConfiguration.RM_BIND_HOST,
                      WebAppUtils.getRMWebAppURLWithoutScheme(this.conf));

    super.serviceInit(this.conf);
  }

附录

hadoop工程的Configuartion架构分析

在这里插入图片描述
父类Configuration的资源加载:

static{
    //print deprecation warning if hadoop-site.xml is found in classpath
    ClassLoader cL = Thread.currentThread().getContextClassLoader();
    if (cL == null) {
      cL = Configuration.class.getClassLoader();
    }
    if(cL.getResource("hadoop-site.xml")!=null) {
      LOG.warn("DEPRECATED: hadoop-site.xml found in the classpath. " +
          "Usage of hadoop-site.xml is deprecated. Instead use core-site.xml, "
          + "mapred-site.xml and hdfs-site.xml to override properties of " +
          "core-default.xml, mapred-default.xml and hdfs-default.xml " +
          "respectively");
    }
    addDefaultResource("core-default.xml");
    addDefaultResource("core-site.xml");
  }

子类YarnConfiguration的资源加载:

static {
    addDeprecatedKeys();
    Configuration.addDefaultResource(YARN_DEFAULT_CONFIGURATION_FILE);
    Configuration.addDefaultResource(YARN_SITE_CONFIGURATION_FILE);
  }
static {
    addDeprecatedKeys();

    // adds the default resources
    Configuration.addDefaultResource("hdfs-default.xml");
    Configuration.addDefaultResource("hdfs-site.xml");

  }

子类JobConf的资源加载:

static{
    ConfigUtil.loadResources();
}
 /**
   * Adds all the deprecated keys. Loads mapred-default.xml and mapred-site.xml
   */
  public static void loadResources() {
    addDeprecatedKeys();
    Configuration.addDefaultResource("mapred-default.xml");
    Configuration.addDefaultResource("mapred-site.xml");
    Configuration.addDefaultResource("yarn-default.xml");
    Configuration.addDefaultResource("yarn-site.xml");
  }  

RM类继承关系

在这里插入图片描述

组件状态

public interface Service extends Closeable {

  /**
   * Service states
   */
  public enum STATE {
    /** Constructed but not initialized */
    NOTINITED(0, "NOTINITED"),

    /** Initialized but not started or stopped */
    INITED(1, "INITED"),

    /** started and not stopped */
    STARTED(2, "STARTED"),

    /** stopped. No further state transitions are permitted */
    STOPPED(3, "STOPPED");

AsyncDispatcher分析

/**

  • Dispatches {@link Event}s in a separate thread. Currently only single thread
  • does that. Potentially there could be multiple channels for each event type
  • class and a thread pool can be used to dispatch the events.
    */

在这里插入图片描述
核心类AsyncDispatcher:异步事件分发器(Yarn中最底层的总管道)
使用BlockingQueue存储事件,并维护一个事件类型和handler的对应map。

public class AsyncDispatcher extends AbstractService implements Dispatcher {
主要的属性
(1)事件队列:    BlockingQueue<Event> eventQueue;
(2)事件分发器:   Map<Class<? extends Enum>, EventHandler> eventDispatchers
(3)处理事件的线程  Thread eventHandlingThread
主要的方法
1、从eventQueue中取出事件以及处理事件
(1)createThread():返回一个Runnable对象,该线程类对象有一个while循环,不断从eventQueue中取出事件(RM启动之后),event = eventQueue.take();然后将事件分发出去dispatch(event)。
(2)dispatch(event):首先得到事件的类型,然后从eventDispatchers中根据事件类型得到相应的事件处理器EventHandler,然后EventHandler.handle(event)对事件进行处理。
2、向eventQueue中添加事件
 AsyncDispatcher 的内部类GenericEventHandler implements EventHanler的handle(event)方法向eventQueue中添加事件eventQueue.put(event);
}

ResourceManager类中的Dispatcher类

ResourceManager类中定义了许多EventDispatcher内部类
RM中存在不同的事件,每种事件具有不同的类型,同一类型的事件交给一个XXXEventDispatcher,XXXEventDispatcher将事件交给真正的事件处理实体进行处理。
RM中定义的XXXEventDispatcher内部类如下:

|事件分发器|处理的事件|事件类型|事件处理实体|
|SchedulerEventDispatcher|SchedulerEvent|enum SchedulerEventType|ResourceScheduler|
                                                      
|RMFatalEventDispatcher|enum RMFatalEventType|enum RMFatalEventType|System.exit(status)|

|ApplicationEventDispatcher|RMAppEvent|RMAppEventType|RMAppImpl|

|RMContainerPreemptEventDispatcher|ContainerPreemptEvent|ContainerPreemptEventType|CapacityScheduler|

ApplicationAttemptEventDispatcher|RMAppAttemptEvent|RMAppAttemptEventType|RMAppAttemptImpl|

|NodeEventDispatcher|RMNodeEvent|RMNodeEventType|RMNodeImpl|

猜你喜欢

转载自blog.csdn.net/weixin_44630798/article/details/88641430