stateMachine
状态机
为了让复杂逻辑更容易维护,代码更容易清晰,明了。YARN 使用了事件触发。事件触发有两个核心概念:中央异步调度器和状态机。 前文介绍了中央异步处理器,本文将介绍YARN 另一核心概念-状态机。
1. 简介
状态机是为了处理单一对象的输入,输出,状态转换逻辑的抽象。在YARN中状态机都跟对象强绑定,代码实现表现为每个对象中都有一个状态机属性。
2. 功能
状态机在功能上能够抽象为:某个对应在某个状态下,因为某个输出,触发某个某个操作,进而变成另一个状态。
3. 设计和实现
3.1 概要
每个对象都有一个属性stateMachine 处理状态转换逻辑
private final StateMachine<RMAppState, RMAppEventType, RMAppEvent>
stateMachine;状态机将对象的输入,状态转换,输出过程梳理为如下五个过程:
1. 在prevState状态,接收到事件event,变成postState状态
2. 在prevState状态,接收到事件event,触发hook操作,变成postState状态
3. 在prevState状态,接收到事件event1或event2或event3,变成postState状态
4. 在prevState状态,接收到事件event1或event2或event3,触发hook操作,变成postState状态
5. 在prevState状态,接收到事件event,触发hook操作,变成postState1或postState2或postState3状态
通过StateMachineFactory 对象实现上面对应过程。
3.2 缓存
StateMachineFactory 其内部维护两个缓存: 1. Map>> stateMachineTable 2. final TransitionsListNode transitionsListNode
stateMachineTable 结构为:
是两层map ,存放状态和事件类型对应的转移操作(很大程度上是为了检索更加方便),表示某个状态碰见某个事件类型,触发什么转换操作。
其存储结构可以通过下图来表示

transitionsListNode
是一个状态转移操作对象(ApplicableSingleOrMultipleTransition)列表,如下图所示
其内部只有一个属性 ApplicableTransition(该接口只有一个方法apply),唯一的实现是ApplicableSingleOrMultipleTransition
ApplicableSingleOrMultipleTransition 有三个属性:
preState 触发前的状态。
eventType 事件类型。
Transition 执行触发操作。
stateMachineTable 需要在 transitionsListNode支持下才能构建。 构建逻辑是:先将所有的状态流转流程和触发操作写入 transitionsListNode,然后遍历transitionsListNode,来构建 stateMachineTable
3.3 状态机构建基本流程
3.3.1 初始化
初始化构造函数1,defaultInitialState 表示这个对象在初始化之后,在状态机中的初始化状态。
3.3.2 添加状态流转过程
上面提到,yarn 抽象来五个状态流转流程,每个流转流程都对应一个addTransition 方法(注意返回值是StateMachineFactory)
最终每个方法执行都是状态机都构造函数2,添加的状态流转流程会放入内部缓存transitionsListNode ,
3.3.3 构建
待所有都状态流转都添加进状态机,状态机就需要开始构建内部缓存。调用的是构造函数3,构造函数 传入的 optimized 参数为true。 该构造函数通过调用makeStateMachineTable() 方法, 该方法将缓存在 transitionsListNode 的流转流程,转换并存到为两层map stateMachineTable
3.4 状态机执行流程
以RMAppImpl 为例,描述状态机是如何使用的
3.4.1 构建状态机
a. 调用StateMachineFactory 第一个构造函数,初始化状态机 b. 调用StateMachineFactory 第二个构造函数,添加状态流转流程 如:添加RMAppNewlySavingTransition 操作
第二个构造函数其实就干了一件事情:构建 transitionsListNode 链
c. 调用StateMachineFactory 第三个构造函数,完成状态机构建,并将状态机赋值给变量stateMachine
d. 将构建到状态机赋值给变量 最终通过make方法将状态机赋值给 stateMachine变量 ,注意make方法返回到是一个InternalStateMachine 对象
InternalStateMachine 对象关键是实现了StateMachine ,并内部存了两个属性: 状态机实例和状态机当前状态
3.4.2 生成事件,触发状态机
以RMAppEventType.START 事件为例 当用户通过Hadoop jar 提交一个mr ,在rm 收到请求之后,rm 的 RMAppManager 服务会创建一个 RMAppEventType.START 类型的RMAppEvent事件 ,并通过下面的方式提交rm的中央调度器中。
3.4.3 状态机内部执行堆栈
a. 接收事件 因为RMAppImpl 本身也是一个事件处理器,而且注册到了RM 到中央异步处理器中,所有可以通过如下方式,感知到有RMAppEvent 事件产生
b. 触发流转操作 执行堆栈: stateMachine.doTransition() -> InternalStateMachine.doTransition() -> StateMachineFactory.this.doTransition() -> SingleInternalArc/MultipleInternalArc.doTransition() -> SingleArcTransition/MultipleArcTransition.transition() -> RMAppTransition.transition() -> RMAppNewlySavingTransition.transition() 在状态机内部,通过如下逻辑找到事件+状态 需要触发的操作 RMAppNewlySavingTransition.transition()
4. YANR 状态转换图
上面详细说明了状态机的实现机理,相信在YARN代码中遇到状态机的代码view的思路就更清晰了。就可以不用纠结状态机的内部逻辑,而直接从状态机构建来了解对象的流转过程,甚至可以通过下图,直接了解resourceManager和NodeManger的各 个对象的状态流转过程。 下面给出通过代码转换来的YARN各个对象的状态转换图


Last updated
Was this helpful?