(相关资料图)
NodeManager(NM)中的状态机分为三类:Application、Container 和 LocalizedResource,它们均直接或者间接参与维护一个应用程序的生命周期。
当 NM 收到某个 Application 的第一个 container 启动命令时,它会创建一个「Application状态机」来跟踪该应用程序在该节点的状态;每个container都有一个独立的「container状态机」;Application 运行所需资源(jar,文件等)的下载过程则由「LocalizedResource状态机」维护和跟踪。二、三类状态机一)Application 状态机NM 上的 Application 维护的信息是 RM 端 Application 信息的一个子集,这有助于统一管理节点上同一个 Application 的所有 Container(例如记录每个 Application 在该节点上运行的 Container 列表,以及杀死一个 Application 的所有 Container 等)。实现这一功能的类是 nodemanager/containermanager/application/ApplicationImpl
,它维护了一个 Application 状态机。需要注意的是,NM 上 Application 的生命周期与 RM 上 Application 的生命周期是一致的。
// 截取 ApplicationImpl 中一部分状态机的代码 private static StateMachineFactory stateMachineFactory = new StateMachineFactory(ApplicationState.NEW) // Transitions from NEW state .addTransition(ApplicationState.NEW, ApplicationState.INITING, ApplicationEventType.INIT_APPLICATION, new AppInitTransition()) .addTransition(ApplicationState.NEW, ApplicationState.NEW, ApplicationEventType.INIT_CONTAINER, INIT_CONTAINER_TRANSITION) // Transitions from INITING state .addTransition(ApplicationState.INITING, ApplicationState.INITING, ApplicationEventType.INIT_CONTAINER, INIT_CONTAINER_TRANSITION) .addTransition(ApplicationState.INITING, EnumSet.of(ApplicationState.FINISHING_CONTAINERS_WAIT, ApplicationState.APPLICATION_RESOURCES_CLEANINGUP), ApplicationEventType.FINISH_APPLICATION, new AppFinishTriggeredTransition()) .addTransition(ApplicationState.INITING, ApplicationState.INITING, ApplicationEventType.APPLICATION_CONTAINER_FINISHED, CONTAINER_DONE_TRANSITION) .addTransition(ApplicationState.INITING, ApplicationState.INITING, ApplicationEventType.APPLICATION_LOG_HANDLING_INITED, new AppLogInitDoneTransition()) .addTransition(ApplicationState.INITING, ApplicationState.INITING, ApplicationEventType.APPLICATION_LOG_HANDLING_FAILED, new AppLogInitFailTransition()) .addTransition(ApplicationState.INITING, ApplicationState.RUNNING, ApplicationEventType.APPLICATION_INITED, new AppInitDoneTransition())
下面进行具体介绍:
1、基本状态NEW:状态机初始状态,每个 Application 对应一个状态机,而每个状态机的初始状态均为 NEW。INITING:Application 处于初始化状态,即创建日志目录和工作目录,创建 AppLogAggregator 对象等。FINISHING_CONTAINERS_WAIT:等待回收 Container 占用的资源时所处的状态。当 Application 状态机收到 FINISH_APPLICATION 事件后,会向各个 Container 发送 KILL 命令以回收它们占用的资源。APPLICATION_RESOURCES_CLEANINGUP:Application 的所有 Container 占用的资源被收回后,它将处于 APPLICATION_RESOURCES_CLEANINGUP 状态。RUNNING:Application 初始化(完成创建日志目录和工作目录,创建 AppLog-Aggregator 等工作)完成后,将进入 RUNNING 状态。FINISHED:Application 将占用的各种文件资源发送给文件删除服务 DeletionService(该服务会异步删除文件,避免产生性能问题)后,进入 FINISHED 状态,表示运行完成。2、基本事件INIT_APPLICATION:NM 收到来自某个 Application 的第一个 Container 后,会触发一个 INIT_APPLICATION 事件,同时使 Application 状态由初始状态 NEW 转换为 INITING。APPLICATION_INITED:Application 初始化完成后将触发一个 APPLICATION_INITED 事件。Application 初始化主要工作是初始化各类必需的服务组件(比如日志记录组件 LogHandler、资源状态追踪组件LocalResourcesTrackerImpl
等),供后续 Container 使用,通常由 Application 的第一个 Container 完成。FINISH_APPLICATION:NodeManager 收到 ResourceManager 发送的待清理的 Application 列表后,会向这些 Application 发送一个 FINISH_APPLICATION 事件APPLICATION_CONTAINER_FINISHED:该 Application 的一个 Container 运行完成(可能运行失败,也可能运行成功)后将触发一个 APPLICATION_CONTAINER_FINISHED 事件。APPLICATION_RESOURCES_CLEANEDUP:Application 所有 Container 占用的资源被清理完成(比如占用的临时目录)后将触发一个 APPLICATION_RESOURCES_CLEANEDUP 事件INIT_CONTAINER:NodeManager 收到 ApplicationMaster 通过 RPC 函数 ContainerManagementProtocol#startContainer
发送的启动 Container 的请求后,会触发一个 INIT_CONTAINER 事件。二)Container 状态机Container 状态机维护一个 container 运行的全部状态,包含 11 个状态和 10 个事件,实现类是 nodemanager/containermanager/container/ContainerImpl.java
。下面是状态转化的图:
下载是在从 init 状态转移到 downloading 状态时,会发一个 REQUEST_RESOURCE_LOCALIZATION
事件。这个事件是会发给 ResourceLocalizationService
,ResourceLocalizationService
根据资源的类型和可见性确定路径并下载他。下载是异步的(并且每个 application 对应着自己的下载线程),每个下载会对应一个 callable 的 FSDownload。状态机如下图所示,非常简单,不再具体介绍。
本篇文章对 NodeManager 中三类状态机进行了介绍,其主要都是维护一个应用程序的生命周期。无需强行记忆,知道有这三类状态机,遇到问题再对应查看即可。
参考文章:《Hadoop技术内幕:深入解析YARN架构设计与实现原理》