前言
继上一篇文章讲述完ApplicationMaster的相关用法,核心主题都是围绕着2个字"应用",当然在RM中还有另外一项比较重要的服务也很重要,他就是节点管理服务,在RM中是如何维系管理多个节点,对于应用管理的话,在RM中已经有了ApplicationMasterService这个服务对象了,那么对应于节点NodeManager来说,难道叫做NodeManagerService吗,听起来非常顺,其实他叫做?ResourceTrackerService,当然名称叫什么都无所谓啦,他扮演的功能就是类似于节点NodeManager大管家的角色了.OK,在这里我们就以NodeManager管理为核心线索,逐步分析RM在此方面的设计思想.
相关涉及类
在分析之前,还是需要了解一下相关类,在阅读本篇文章之前,可以建议大家阅读我的上一篇文章ApplicationMaster文章的分析,因为NM和AM管理许多思想共同,也有共同的父类,比如AbstractService这样的抽象服务类.下面是我归纳出的几个类.
1.NodeManager.java--节点管理类,这个类是yarn-resourcemanager包中的类,不是yarn-nodemanager中的同名类,这个类是本篇文章的核心角色类,
2.NodesListManager--节点列表管理类,这个类中管理了类似黑名单,白名单的节点列表形式。
3.NMLivelinessMonitor--节点存活状态监控线程类,与之前的AMLivelinessMonitor线程的原理类似,最简单的心跳更新检查。
4.ResourceTrackerService--节点服务管理对象,负责与各个NodeManager通信。包括NM在此服务上的注册请求处理,心跳更新操作等等。
下面是一张结构简图帮助大家宏观上理解RM中的NM管理:
NodeManager节点注册
我们从一个比较初始的状态出发,比如说节点注册开始,一步步的贯穿的去分析整个流程。节点注册操作,在NodeManager类自身中。这个类中定义的基本信息如下
//ResourceManager下资源管理器类
public class NodeManager implements ContainerManagementProtocol {
private static final Log LOG = LogFactory.getLog(NodeManager.class);
private static final RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null);
final private String containerManagerAddress;
//节点通信地址
final private String nodeHttpAddress;
//所在机架名称
final private String rackName;
//节点ID
final private NodeId nodeId;
final private Resource capability;
Resource available = recordFactory.newRecordInstance(Resource.class);
Resource used = recordFactory.newRecordInstance(Resource.class);
注册操作并没有独立出方法来,而是包含在了构造函数中,也就是说,当你构造新的NodeManager的时候,你已经在注册节点到ResourceTrackerService。
public NodeManager(String hostName, int containerManagerPort, int httpPort,
String rackName, Resource capability,
ResourceTrackerService resourceTrackerService, RMContext rmContext)
throws IOException, YarnException {
this.containerManagerAddress = hostName + ":" + containerManagerPort;
this.nodeHttpAddress = hostName + ":" + httpPort;
this.rackName = rackName;
this.resourceTrackerService = resourceTrackerService;
this.capability = capability;
Resources.addTo(available, capability);
this.nodeId = NodeId.newInstance(hostName, containerManagerPort);
//新建nodemanager注册请求
RegisterNodeManagerRequest request = recordFactory
.newRecordInstance(RegisterNodeManagerRequest.class);