Yarn中的状态机库及其使用

状态机库

        状态机由一组状态组成,这些状态分为三类:初始状态、中间状态和最终状态。状态机从初始状态开始运行,经过一系列中间状态后,到达最终状态并退出。在一个状态机中,每个状态都可以接收一组特定事件,并根据具体的事件类型转换到另一个状态。当状态机转换到最终状态时,则退出。

YARN状态转换方式

        在YARN中,每种状态转换由一个四元组表示,分别是转换前状态(preState)、转换后状态(postState)、事件(event)和回调函数(hook)。YARN定义了三种状态转换方式,具体如下:

1)一个初始状态、一个最终状态、一种事件(见下图)。该方式表示状态机在preState状态下,接收到Event事件后,执行函数状态转移函数Hook,并在执行完成后将当前状态转换为postState。

 

2)一个初始状态、多个最终状态、一种事件(见下图)。该方式表示状态机在preState状态下,接收到Event事件后,执行函数状态转移函数Hook,并将当前状态转移为函数Hook的返回值所表示的状态。

3)一个初始状态、一个最终状态、多种事件(见图下图)。该方式表示状态机在preState状态下,接收到Event1、Event2和Event3中的任何一个事件,将执行函数状态转移函数Hook,并在执行完成后将当前状态转换为postState。

 

       YARN自己实现了一个非常简单的状态机库(位于包org.apache.hadcop.yarn.state中),具体如图所示。YARN对外提供了一个状态机工厂StatemachineFactory,它提供多种addTransition方法供用户添加各种状态转移,一旦状态机添加完毕后,可通过调用installTopology完成一个状态机的构建。

状态机的使用方法

        接下来来看一个状态机应用实例,在该实例中,创建一个作业状态机JobStateMachine,该状态机维护作业内部的各种状态变化。该状态机同时也是一个事件处理器,当接收到某种事件后,会触发相应的状态转移。

1)定义作业类型

public enum JobEventType {
  JOB_KILL,
  JOB_INIT,
  JOB_START,
  JOB_SETUP_COMPLETED,
  JOB_COMPLETED
} 

2)定义作业状态机

public class JobStateMachine implements EventHandler<JobEvent>{
  private final String jobID;
  private EventHandler eventHandler;
  private final Lock writeLock;
  private final Lock readLock;
  
  // 定义状态机
  protected static final
    StateMachineFactory<JobStateMachine, JobStateInternal, JobEventType, JobEvent>
      stateMachineFactory
        = new StateMachineFactory<JobStateMachine, JobStateInternal, JobEventType, JobEvent>
          (JobStateInternal.NEW)
          
          .addTransition(JobStateInternal.NEW, JobStateInternal.INITED,
                JobEventType.JOB_INIT,
                new InitTransition())
          .addTransition(JobStateInternal.INITED, JobStateInternal.SETUP,
                JobEventType.JOB_START,
                new StartTransition())
          .addTransition(JobStateInternal.SETUP, JobStateInternal.RUNNING,
                JobEventType.JOB_SETUP_COMPLETED,
                new SetupCompletedTransition())
          .addTransition
                (JobStateInternal.RUNNING,
                EnumSet.of(JobStateInternal.KILLED, JobStateInternal.SUCCEEDED),
                JobEventType.JOB_COMPLETED,
                new JobTasksCompletedTransition())
          .installTopology();
        
  private final StateMachine<JobStateInternal, JobEventType, JobEvent> stateMachine;
  
  public JobStateMachine(String jobID, EventHandler eventHandler) {
    this.jobID = jobID;
    ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    this.readLock = readWriteLock.readLock();
    this.writeLock = readWriteLock.writeLock();
    this.eventHandler = eventHandler;
    stateMachine = stateMachineFactory.make(this);
  }
  
  protected StateMachine<JobStateInternal, JobEventType, JobEvent> getStateMachine() {
    return stateMachine;
  }
  
  public static class InitTransition
    implements SingleArcTransition<JobStateMachine, JobEvent> {
      @Override
      public void transition(JobStateMachine job, JobEvent event) {
        System.out.println("Receiving event " + event);
        job.eventHandler.handle(new JobEvent(job.getJobId(), JobEventType.JOB_START));
      }
  }
  
  public static class StartTransition
    implements SingleArcTransition<JobStateMachine, JobEvent> {
      @Override
      public void transition(JobStateMachine job, JobEvent event) {
        System.out.println("Receiving event " + event);
        job.eventHandler.handle(new JobEvent(job.getJobId(), JobEventType.JOB_SETUP_COMPLETED));
      }
  }
  
  // ......
  // 定义类SetupCompletedTransition和JobTasksCompletedTransition
  
  @Override
  public void handle(JobEvent event) {
    try {
      writeLock.lock();
      JobStateInternal oldState = getInternalState();
      try {
        getStateMachine().doTransition(event.getType(), event);
        } catch (InvalidStateTransitonException e) {
        System.out.println("Can't handle this event at current state");
      }
      if (oldState != getInternalState()) {
        System.out.println("Job Transitioned from " + oldState + " to "
                  + getInternalState());
      }
    }
    finally {
      writeLock.unlock();
    }
  }
  
  public JobStateInternal getInternalState() {
    readLock.lock();
    try {
      return getStateMachine().getCurrentState();
    } finally {
    readLock.unlock();
    }
  }
  
  public enum JobStateInternal { // 作业内部状态
    NEW,
    SETUP,
    INITED,
    RUNNING,
    SUCCEEDED,
    KILLED,
  }
}

状态机可视化

        YARN中实现了多个状态机对象,包括ResourceManager中的RMAppImpl、RMAppAttemptImpl、RMContainerImpl和RMNodeImpl,NodeManager中的ApplicationImpl、ContainerImpl和LocalizedResource,MRAppMaster中的JobImpl、TaskImpl和TaskAttemptImpl等。为了便于用户查看这些状态机的状态变化以及相关事件,YARN提供了一个状态机可视化工具,具体操作步骤如下:

   步骤1   将状态机转化为graphviz(.gv)格式的文件,编译命令如下:

mvn compile -Pvisualize

   经过该步骤后,本地目录中生成了ResourceManager.gv、NodeManager.gv和MapReduce.gv三个graphviz格式的文件(有兴趣可以直接打开查看具体内容)。

   步骤2   使用可视化包graphviz中的相关命令生成状态机图,Shell命令具体如下:

dot -Tpng NodeManager.gv > NodeManager.png

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值