本文主要是介绍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) 定义作业状态机。
@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);
}
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
如果尚未安装 graphviz 包, 操作该步骤之前先要安装该包。
这篇关于YARN 状态机库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!