AM注册到RM
1. 从Yarn源码剖析(三)-- ApplicationMaster的启动可知提交应用程序至yarn时最后启动了ApplicationMaster类,所以我们直接来看这个类(是spark自己封装的AM)的main方法,可以看到spark是通过调用AMRMClient客户端来调用相关API来实现AM注册的,以及资源的调度。
amClient = AMRMClient.createAMRMClient() //创建一个客户端实例
amClient.init(conf) //初始化
amClient.start() //启动客户端
this.uiHistoryAddress = uiHistoryAddress
val trackingUrl = uiAddress.getOrElse {
if (sparkConf.get(ALLOW_HISTORY_SERVER_TRACKING_URL)) uiHistoryAddress else ""
}
logInfo("Registering the ApplicationMaster")
synchronized {
amClient.registerApplicationMaster(Utils.localHostName(), 0, trackingUrl) //注册AM
registered = true
}
2. 那我们就对应这几个API到hadoop源码中去剖析AM注册启动的过程,先从AMRMClient.createAMRMClient()入手,我们找到hadoop代码中org.apache.hadoop.yarn.client.api.AMRMClient这个类(hadoop是2.7.4版本的代码),可以看到就是new了一个实现类AMRMClientImpl
public static <T extends ContainerRequest> AMRMClient<T> createAMRMClient() {
AMRMClient<T> client = new AMRMClientImpl<T>();
return client;
}
3. 接下来看一下amClient.init(conf)的初始化方法,那我们这里显然是由 AMRMClientImpl()实现,因此我们去看它的serviceInit(),内部就是把配置文件做了一个初始化,就不多做分析了。接着看amClient.start()方法,它同init()方法一样,相关的初始化和启动方法在Yarn源码剖析(一) --- RM与NM服务启动以及心跳通信有做介绍,显然也是由AMRMClientImpl()实现的,内部就实现了为指定的协议创建资源管理器的代理。至此AM服务的初始化、启动就完成了,接下来就是注册这个AM到RM上了,从spark端的代码中可以看到,是调用了AMRMClient.registerApplicationMaster()方法。
synchronized {
amClient.registerApplicationMaster(Utils.localHostName(), 0, trackingUrl)
registered = true
}
4. 那我们就来看一下这个代码AMRMClient.registerApplicationMaster(),由它的实现类AMRMClientImpl()实现。
private RegisterApplicationMasterResponse registerApplicationMaster()
throws YarnException, IOException {
//设置资源请求
RegisterApplicationMasterRequest request =
RegisterApplicationMasterRequest.newInstance(this.appHostName,
this.appHostPort, this.appTrackingUrl);
//获取响应
RegisterApplicationMasterResponse response =
rmClient.registerApplicationMaster(request); //关键方法
synchronized (this)