javazx 发表于 2017-4-17 14:04:29

《深入解析YARN架构设计与实现原理》第3章 YARN基础库【3.5】

3.5 状态机库
状态机由一组状态组成, 这些状态分为三类: 初始状态、 中间状态和最终状态。 状态机从初始状态开始运行, 经过一系列中
间状态后, 到达最终状态并退出。 在一个状态机中, 每个状态都可以接收一组特定事件, 并根据具体的事件类型转换到另一个状
态。 当状态机转换到最终状态时, 则退出。
3.5.1 YARN状态转换方式
在YARN中, 每种状态转换由一个四元组表示, 分别是转换前状态( preState) 、 转换后状态( postState) 、 事件( event) 和
回调函数( hook) 。 YARN定义了三种状态转换方式, 具体如下:
1) 一个初始状态、 一个最终状态、 一种事件( 见图3-18) 。 该方式表示状态机在preState状态下, 接收到Event事件后, 执行
函数状态转移函数Hook, 并在执行完成后将当前状态转换为postState。
图3-18 初始状态:最终状态:事件=1:1:1
2) 一个初始状态、 多个最终状态、 一种事件( 见图3-19) 。 该方式表示状态机在preState状态下, 接收到Event事件后, 执行
函数状态转移函数Hook, 并将当前状态转移为函数Hook的返回值所表示的状态。
图3-19 初始状态:最终状态:事件=1:N :1
3) 一个初始状态、 一个最终状态、 多种事件( 见图3-20) 。 该方式表示状态机在preState状态下, 接收到Event1、 Event2和
Event3中的任何一个事件, 将执行函数状态转移函数Hook, 并在执行完成后将当前状态转换为postState。
图3-20 初始状态:最终状态:事件=1:1:N
3.5.2 状态机类
YARN自己实现了一个非常简单的状态机库( 位于包org.apache.hadcop.yarn.state中) , 具体如图3-21所示。 YARN对外提供了
一个状态机工厂StatemachineFactory, 它提供多种addTransition方法供用户添加各种状态转移, 一旦状态机添加完毕后, 可通过调
用installTopology完成一个状态机的构建。
图3-21 状态机类图
3.5.3 状态机的使用方法
本小节将给出一个状态机应用实例, 在该实例中, 创建一个作业状态机JobStateMachine, 该状态机维护作业内部的各种状态
变化。 该状态机同时也是一个事件处理器, 当接收到某种事件后, 会触发相应的状态转移。 该实例中没有给出一个中央异步调度
器, 可以嵌到3.4.3节的实例程序中运行。
1) 定义作业类型。
public enum JobEventType {
JOB_KILL,
JOB_INIT,
JOB_START,
JOB_SETUP_COMPLETED,
JOB_COMPLETED
}
2) 定义作业状态机。
@SuppressWarnings({ "rawtypes", "unchecked" })
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);
}p
rotected StateMachine<JobStateInternal, JobEventType, JobEvent> getStateMachine() {
return stateMachine;
} p
ublic 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));
}
} p
ublic 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");
}i
f (oldState != getInternalState()) {
System.out.println("Job Transitioned from " + oldState + " to "
+ getInternalState());
}
}f
inally {
writeLock.unlock();
}
} p
ublic JobStateInternal getInternalState() {
readLock.lock();
try {
return getStateMachine().getCurrentState();
} finally {
readLock.unlock();
}
}p
ublic enum JobStateInternal { //作业内部状态
NEW,
SETUP,
INITED,
RUNNING,
SUCCEEDED,
KILLED,
}
}
3.5.4 状态机可视化
YARN中实现了多个状态机对象, 包括ResourceManager中的RMAppImpl、 RMApp-AttemptImpl、 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
如果尚未安装graphviz包, 操作该步骤之前先要安装该包。
注释
参见网址https://issues.apache.org/jira/browse/MAPREDUCE-2930。


页: [1]
查看完整版本: 《深入解析YARN架构设计与实现原理》第3章 YARN基础库【3.5】