【概述】
上一篇文章中提到了,nm进程重启后会根据记录的信息进行恢复或重新创建container进程,那么NM将container的哪些信息记录到了本地,重启过程中又是如何读取并恢复的,本文就来聊聊相关的原理。
【状态持久化】
首先,NM只有在使能了重启恢复container了之后,
即yarn.nodemanager.recovery.enabled配置为true,默认不开启。
启动运行container的过程中,才会将相关信息和状态持久化存储在本地。
持久化存储采用了leveldb的方式,即以key,value的形式记录相关信息。具体保存的信息如下面表格所示:
Key | Value与存储时机 |
$AppPrefix/$AppID | value为appID,提交用户,app的acl策略,日志聚合上下文,证书等整合的信息 创建Application时存储 |
$ContainerPrefix/$ContainerID/request | value为container创建请求序列化后的字节数据 创建container时存储 |
$ContainerPrefix/$ContainerID/launched | value为空 container进程被创建后存储 |
$ContainerPrefix/$ContainerID/version | value为container的版本信息,从对应的token中获取 container资源变更时存储 |
$ContainerPrefix/$ContainerID/resourceChanged | value为运行过程中动态调整的资源(包括CPU和内存) |
$ContainerPrefix/$ContainerID/killed | value为空 container被kill时存储 |
$ContainerPrefix/$ContainerID/exitcode | value为container进程结束时的退出码 container结束时存储 |
$AppPrefix为App的固定前缀,具体值为"ContainerManager/applications/"
$AppID为Application的ID
$ContainerPrefix为container的固定前缀,具体值为"ContainerManager/containers/"
$ContainerID为container的ID
从上面的记录可以看出来,app信息主要是记录ID,用于关联相关的container,而container则记录了请求启动的上下文信息,然后又以不同的key记录了container的不同状态,以及资源变更的情况。
PS:结合《yarn任务提交启动流程》中的图可以更清楚的知晓信息存储的时机。
【重启后的恢复】
NM重启后,container的大概恢复流程如下图所示:
从文件中加载所有app相关的信息,并为每个app创建对应的实例对象
给每个app实例对象发送initApplication事件,进行app的初始化处理。
从文件中加载所有container相关的信息,并根据这些信息构建对应的container实例对象。
给container对应的app发送initContainer事件,事件中会携带Container的ID。
app处理initContainer事件会给对应的container发送init事件。
container收到init事件后,进行内部的逻辑判断,如果已经记录了结束状态(恢复文件中包含container的exitcode记录),则直接跳转到DONE状态;如果存在kill记录,则进行清理动作,然后也跳转到DONE状态;如果未包含这两个状态,则按照正常流程,进行后续步骤与状态机跳转,直到创建container进程。
注意:
如果存储信息中包含除了上面记录之外的,无法识别的,并且是具有相同container前缀和id的key,统统认为是非法的key,重启恢复过程中,会将恢复的状态置为killed,在上面第4步之后,给container发送kill事件,触发进行清理结束动作和状态机的流转
containerLaunch服务模块在启动container进程后,会将container进程对应的PID信息写入本地磁盘文件中。重启恢复再次收到启动container进程的请求后,会先到指定的目录查看是否有对应的PID文件,并判断对应的PID进程是否还存在,如果存在则不进行实际的启动动作,否则会创建对应的进程。
【总结】
实际上,NM使能重启恢复后,持久化记录的不仅仅只有app和container的信息,还包括本地化的资源情况,以及用于认证的token信息,这样可以加速container恢复的速度。
另外,如果RM如果感知NM心跳超时后,会进行相关的清除动作,在此之后,NM重启恢复创建相关container进程,然后通过心跳汇报给RM,RM校验判断app或container不存在或已结束的话,会告知NM结束对应进程并进行相关的清理。
好了,本文就聊到这里。
原创不易,点赞,在看,分享是最好的支持, 谢谢~