为了进一步说明YARN RPC的使用方法,本小节给出一个具体的应用实例。
在YARN中,ResourceManager和NodeManager之间的通信协议是ResourceTracker,其中NodeManager是该协议的客户端,ResourceManager是服务端,NodeManager通过该协议中定义的两个RPC函数(registerNodeManager和nodeHeartbeat)向ResourceManager注册和周期性发送心跳信息。ResourceManager(服务器端)中的相关代码如下:
- // ResourceTrackerService实现了ResourceTracker通信接口,并启动RPC Server
- public class ResourceTrackerService extends AbstractService implements
- ResourceTracker {
- private Server server;
- ...
- protected void serviceStart() throws Exception {
- super.serviceStart();
- Configuration conf = getConfig();
- YarnRPC rpc = YarnRPC.create(conf); //使用YarnRPC类
- this.server = rpc.getServer(ResourceTracker.class, this, resourceTrackerAddress,
- conf, null, conf.getInt(YarnConfiguration.RM_RESOURCE_TRACKER_CLIENT_THREAD_COUNT,
- YarnConfiguration.DEFAULT_RM_RESOURCE_TRACKER_CLIENT_THREAD_COUNT));
- this.server.start();
- }
- ...
- @Override
- public RegisterNodeManagerResponse registerNodeManager(
- RegisterNodeManagerRequest request) throws YarnException,
- IOException {
- //具体实现
- }
- @Override
- public NodeHeartbeatResponse nodeHeartbeat(NodeHeartbeatRequest request)
- throws YarnException, IOException {
- //具体实现
- }
- }
NodeManager(客户端)中的相关代码如下。
- // 该函数是从YARN源代码中简单修改而来的
- protected ResourceTracker getRMClient() throws IOException {
- Configuration conf = getConfig();
- InetSocketAddress rmAddress = getRMAddress(conf, protocol);
- RetryPolicy retryPolicy = createRetryPolicy(conf);
- ResourceTracker proxy = RMProxy.<T>getProxy(conf, ResourceTracker.class, rmAddress);
- LOG.info("Connecting to ResourceManager at " + rmAddress);
- return (ResourceTracker) RetryProxy.create(protocol, proxy, retryPolicy);
- }
- ...
- this.resourceTracker = getRMClient();
- ...
- RegisterNodeManagerResponse regNMResponse = resourceTracker.registerNodeManager(request);
- ...
- response = resourceTracker.nodeHeartbeat(request);
为了能够让以上代码正常工作,YARN按照以下流程实现各种功能。
步骤1 定义通信协议接口(Java Interface)。定义通信协议接口ResourceTracker,它包含registerNodeManager和nodeHeartbeat两个函数,且每个函数包含一个参数和一个返回值,具体如下:
- public interface ResourceTracker {
- public RegisterNodeManagerResponse registerNodeManager(
- RegisterNodeManagerRequest request) throws YarnException, IOException;
- public NodeHeartbeatResponse nodeHeartbeat(NodeHeartbeatRequest request)
- throws YarnException, IOException;
- }
步骤2 为通信协议ResourceTracker提供Protocol Buffers定义和Java实现。前面提到,Protocol Buffers仅提供了序列化框架,但未提供RPC实现,因此RPC部分需要由用户自己实现,而YARN则让ResourceTrackerService类实现了ResourceTracker协议,它的Protocol Buffers定义(具体见文件ResourceTracker.proto)如下:
- option java_package = "org.apache.hadoop.yarn.proto";
- option java_outer_classname = "ResourceTracker";
- option java_generic_services = true;
- option java_generate_equals_and_hash = true;
- import "yarn_server_common_service_protos.proto";
- service ResourceTrackerService {
- rpc registerNodeManager(RegisterNodeManagerRequestProto) returns (RegisterNodeManagerResponseProto);
- rpc nodeHeartbeat(NodeHeartbeatRequestProto) returns (NodeHeartbeatResponseProto);
- }
ResourceTracker的RPC函数实现是由ResourceManager中的ResourceTrackerService完成的。