Yarn状态机设计


发布于 2024-07-30 / 66 阅读 / 0 评论 /
本文基于Hadoop-3.5.0,解读Yarn的状态机

在Yarn中,每种状态转换由一个四元组组成——转换前状态(preState)、转换后状态(postState)、事件(event)、回调函数or转换器(hook or transaction)。

Yarn状态机的抽象是org.apache.hadoop.yarn.state.StateMachine,抽象类中定义了doTransition方法,用于对Event信息进行处理。

public STATE doTransition(EVENTTYPE eventType, EVENT event)
        throws InvalidStateTransitionException;

具体处理转换的逻辑通过StateMachineFactory.addTransition方法来完成,此方法主要是绑定了preState、postState、event、hook这个四元组,hook就是真正的处理逻辑。

1.状态转换模式

状态机有三种转换模式

1.1.一对一模式

模式中只有一个初始状态、一个最终状态、以及一种事件。如下图所示:

对应源码org.apache.hadoop.yarn.state.StateMachineFactory.SingleInternalArc

1.2.多postState模式

模式中有一个初始状态、多个最终状态、一种事件。具体选择哪个最终状态,由事件的处理结果决定。如下图所示:

对应源码org.apache.hadoop.yarn.state.StateMachineFactory.MultipleInternalArc

1.3.多event模式

模式中有一个初始状态、一个最终状态、以及多种事件。不同的事件可能触发不同的状态转换。如下图所示:

对应源码org.apache.hadoop.yarn.state.StateMachineFactory.SingleInternalArc

2.Yarn的状态机实例

Yarn有多个状态机实例,分布于不同的角色中。

2.1.ResourceManager中的状态机

包括RMAppImpl、RMAppAttemptImpl、RMContainerImpl、RMNodeImpl。

2.1.1.RMAppImpl

RMAppImpl的全称为org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppImpl,是org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp的实现类。其类结构如下图所示:

RM内部维护着所有Application的状态。对于每个Application都有一个RMApp对象与之对应。在RMApp的实现类RMAppImpl中,维护着对象的基本信息,包括起始时间、提交用户、队列和状态机等信息。

private static final StateMachineFactory<RMAppImpl,RMAppState, RMAppEventType, RMAppEvent> stateMachineFactory 
= new StateMachineFactory<RMAppImpl, RMAppState, RMAppEventType, RMAppEvent>(RMAppState.NEW)
.addTransition(……)
……
.installTopology();

this.stateMachine = stateMachineFactory.make(this);

状态机工厂如上所示,定义了RMAppImpl中状态机的状态及其事件处理流程。状态机的状态有以下11种。

(1)NEW

RMApp的初始状态,当客户端通过RPC调用RM的submitApplication方法后,RM会初始化RMAppImpl,此时状态机的状态被设置为NEW。

(2)NEW_SAVING

表示RM在处理客户端提交作业的请求期间状态为NEW_SAVING。RM的submitApplication方法中,在返回给客户端前,RM会创建START事件,当NEW状态遇到START事件后,RMAppImpl的状态转换为NEW_SAVING。

(3)SUBMITTED

表示App已经提交成功,RM已经存下该App状态。两种情况下会转换为SUBMITTED状态:

  • 当RMAppImpl的状态由NEW转换为NEW_SAVING期间,会触发RMAppNewlySavingTransition的transition方法,在此方法中会调用RMStateStore存储RMAppImpl,事实上是在RMStateStore.ForwardingEventHandler中调用handleStoreEvent方法存储RMAppImpl,完成存储后会调用notifyDoneStoringApplication方法,在此方法中创建RMAppNewSavedEvent事件并交给rmDispatcher。RMAppImpl遇到RMAppNewSavedEvent(对应APP_NEW_SAVED)事件后,状态转换为SUBMITTED。

  • 在NEW状态下,如果是Recover模式,且该App存储在RMStateStore中,则转换为SUBMITTED。

(4)ACCEPTED

表示该App已经提交给调度器。

在NEW_SAVING转换为SUBMITTED状态的时候,RMAppImpl会触发StartAppAttemptTransition,这时会创建一个新的RMAppAttempt,然后新建RMAppAttemptEventType.START事件给处理器,经过RMAppAttempt处理机。当该RMAppAttempt交给调度器(的某个组)后,状态改为ACCEPTED。

(5)RUNNING

AM已经启动并注册到RM上。两种情况下会转换为RUNNING状态:

  • AM启动后会向RM注册,这时候会触发RMAppImpl状态转换为RUNNING状态。

  • RMAppImpl也有可能在Recovery模式下转换为RUNNING。

(6)FINAL_SAVING

FINAL_SAVING状态表示正在保存RMAppImpl到存储器,目的是保证RMAppImpl的状态已经存储下来,当RMStateStore在完成App状态更新到存储器后会根据App的状态转换为最终状态,包括FAILED,FINISHED,FINISHING,KILLED。

这个状态其实阻断了原来清晰的状态转换流程,如RUNNING在遇到RMAppEventType.ATTEMPT_FAILED时,转换为FINAL_SAVING状态,但是设置了targetedFinalState为RMAppState.FAILED,最终经过FINAL_SAVING后转换为RMAppState.FAILED状态。

(7)FINISHING

FINISHING状态表示RM上相应的App状态已经完成存储工作,在等待RMAppEventType.ATTEMPT_FINISHED事件。因为只有RMAppAttempt结束后RMApp才能结束。

在RMAppState.RUNNING状态遇到RMAppEventType.ATTEMPT_UNREGISTERED事件时,RMAppImpl转换为FINAL_SAVING,并存储targetedFinalState为RMAppState.FINISHING,遇到RMAppEventType.APP_UPDATE_SAVED事件后RMAppImpl转换为FINISHING状态。

(8)FINISHED

RMAppImpl的结束状态(另外两个结束状态是KILLED和FAILED),正常情况下处于RUNNING的RMAppImpl成功结束后状态就是FINISHED,另外RM收到AM的REJECTED请求后最终状态也是FINISHED,即FINISHED状态是AM主动通知RM自己结束后的状态。

(9)FAILED

处于FINAL_SAVING的RMAppImpl遇到RMAppEventType. FAILED事件后RMAppImpl转换为FAILED状态。

(10)KILLING

RMAppImpl遇到客户端执行KILL操作后会转换为FINAL_SAVING状态,另外会设置RMAppImpl的targetedFinalState为RMAppEventType.KILL。

(11)KILLED

处于FINAL_SAVING的RMAppImpl遇到RMAppEventType.APP_UPDATE_SAVED事件后RMAppImpl转换为KILLED状态。

2.2.NodeManager中的状态机

包括ApplicationImpl、ContainerImpl、LocalizedResource。

2.3.MRAppMaster中的状态机

包括JobImpl、TaskImpl、TaskAttemptImpl。