YARN RM failover机制
RM(ResourceManager)每次在启动之前都会进行初始化并执行一次recovery操作,然后才启动RM,对外提供服务。
RM启动流程如下图:
RM启动流程图
RM中的各种服务包括:
(1)、ContainerAllocationExpirer:监控Containter是否到期。
(2)、AmLivelinessMonitor:监控App的存活状态。
(3)、NodesListManager:node列表管理,可以动态往集群中添加节点或者减少节点。
(4)、NMLivelinessMonitor:监控各个NodeManager是否存活,默认情况下,如果某个NodeManage在10min内未汇报心跳,则认为该节点出现故障。
(5)、ResourceTrackerService:实现了ResourceTracker协议,主要负责管理各个
NodeManager,如新NodeManager注册,死NodeManager的剔除。
(6)、ApplicationMasterService:实现了AMRMProtocol通信协议,负责与
ApplicationMaster交互,接收来自ApplicationMaster的请求并作出相应。
(7)、ClientRMService:实现ClientRMProtocal协议,负责与client交互,接收来自client
端的请求并作出响应。
(8)、AdminService:实现RMAdminProtocol协议,主要负责整个系统权限管理,如哪些client可以修改系统中队列名称,给某些队列增加资源等。
(9)、ApplicationMasterLauncher:管理ApplicationMaster的启动和退出。
一、RECOVERY的目标
l App恢复:未执行完成的App在RM重启之后重新执行
App恢复的三种策略:
<1>、整个作业重新计算
<2>、保存已经完成的map task和reduce task,只重新计算未完成的task
<3>、保存task的进度,从task断点处开始计算,如:某个task完成了20%,则AM重启后,让该task从20%处开始计算。
(第三种方案基本不可能实现,因为作业执行时,有时会保存几个全局变量,如全局counter,自定义的变量,这些东西由用户的程序控制,框架很难获取到他们的值并持久化到磁盘上以便恢复。)
l 资源恢复:重新注册集群中的节点(NodeManager)信息到RM
二、YARN关于RM恢复已做的工作
1、RM的状态信息
YARN中RM的状态信息包括两种:
l 一种是RMNode,集群中节点(NodeManager)的状态信息
l 一种是ApplicationInfo,提交的应用状态信息
2、RM状态存储方式
RM状态信息目前YARN只提供了两种存储方式:
l 一种是基于内存的方式存储(MemStore)
l 一种是基于ZK的方式存储(ZKStore)
具体选择那种存储方式可以用以下参数配置:
yarn.resourcemanager.store.class:配置RM状态信息存储方式,有MemStore和ZKStore。
yarn.resourcemanager.zookeeper-store.address:当使用ZK存储时,指定在ZK上的存储地址。
3、RM的恢复[不可用]
YARN目前鉴于是内测版,RM恢复部分实现了部分代码,总体是不可用的,只供参考,部分关键代码如下。
<1>、RMNode的恢复:
重新将集群的节点信息注册到RM。
ResourceTrackerService中的代码如下:
public void recover(RMState state) {
List<RMNode>nodeManagers = state.getStoredNodeManagers();
for (RMNode nm :nodeManagers) {
createNewNode(nm.getNodeID(), nm.getNodeHostName(), nm
.getCommandPort(),nm.getHttpPort(), nm.getNode(), nm
.getTotalCapability());
}
for(Map.Entry<ApplicationId, ApplicationInfo> entry : state
.getStoredApplications().entrySet()){
List<Container>containers = entry.getValue().getContainers();
List<Container>containersToAdd = new ArrayList<Container>();
for (Container c :containers) {
RMNode containerNode= this.rmContext.getNodesCollection()
.getNodeInfo(c.getNodeId());
containersToAdd.add(c);
containerNode.allocateContainer(entry.getKey(), containersToAdd);
containersToAdd.clear();
}
}
}
<2>、ApplicationInfo的恢复:
调用资源调度算法(CapacityScheduler、FairScheduler、FifoScheduler)重新分配资源(Container)并重新执行未执行完成的App。
资源调度算法采用以下参数进行配置:yarn.resourcemanager.scheduler.class,默认采用:org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler容量调度算法。
CapacityScheduler中代码如下:
@Lock(Lock.NoLock.class)
public void recover(RMState state) throws Exception {
applications.clear();
for (Map.Entry<ApplicationId, ApplicationInfo> entry :state.getStoredApplications().entrySet()) {
ApplicationId appId = entry.getKey();
ApplicationInfo appInfo =entry.getValue();
SchedulerApp app = applications.get(appId);
app.allocate(appInfo.getContainers());
for (Container c: entry.getValue().getContainers()) {
Queue queue = queues.get(appInfo.getApplicationSubmissionContext().getQueue());
queue.recoverContainer(clusterResource, applications.get(appId), c);
}
}
}
三、YARN关于RM恢复没做的工作
<1>、RM状态信息何时存储
<2>、RM失败后根据状态进行恢复
四、hadoop YARN jira上的讨论
目前在hadoopYARN jira上针对RM recovery的讨论,主要集中在以下几方面:
第一点:RM恢复需要那些状态信息
一种观点是只需要存储还没有执行完成的App的信息。
一种观点是既要存储App的信息,还要存储NM的信息,如当前YARN部分实现的那样。
第二点:RM状态信息何时进行存储
第三点:RM状态信息的存储方式
有三种存储方式可以选择:
MemStore:内存存储
DiskStore:磁盘存储
ZKStore:ZooKeeper存储
第四点:RM失败后如何进行恢复
参考链接如下:
https://issues.apache.org/jira/browse/YARN-128
https://issues.apache.org/jira/browse/MAPREDUCE-4343
https://issues.apache.org/jira/secure/attachment/12549649/YARN-128.patch
https://issues.apache.org/jira/secure/attachment/12532336/MR-4343.1.patch
更多精彩博客请访问:http://yuntai.1kapp.com/
申明:该博客为原创博客,链接http://yuntai.1kapp.com/?p=546对应的博客内容是我写的,但是是其他同事发表的。