hadoop rpc

来源:互联网 发布:雕刻软件type3 编辑:程序博客网 时间:2024/05/22 18:40
     RPC 是一种通过网络从远程计算机上请求服务,但不需要了解底层网络技术的协议。RPC 协议假定某些传输协议(如 TCP 或 UDP 等)已经存在,并通过这些传输协议为通信程序之间传递访问请求或者应答信息。在 OSI 网络通信模型中,RPC 跨越了传输层和应用层。RPC 使得开发分布式应用程序更加容易。

       一  RPC 总体架构

     二 使用方法

     Hadoop RPC 对外主要提供了两种接口(见类org.apache.hadoop.ipc.RPC),分别是:
    1. public static <T> ProtocolProxy <T> getProxy/waitForProxy(…) :构造一个客户端代理对象(该对象实现了某个协议),用于向服务器发送RPC 请求。

    2.public static Server RPC.Builder (Configuration).build() ❑ :为某个协议(实际上是 Java接口)实例构造一个服务器对象,用于处理客户端发送的请求。

    示例如下

定义rpc 协议代码
  1. public interface TestProtocol extends VersionedProtocol {  
  2.     long versionID = 1L;  
  3.   
  4.     String echo(String msg);  
  5. }  
实现rpc 协议代码
  1. public class TestProtocolImpl implements TestProtocol {  
  2.   
  3.     @Override  
  4.     public long getProtocolVersion(String protocol, long clientVersion) throws IOException {  
  5.         return TestProtocol.versionID;  
  6.     }  
  7.   
  8.     @Override  
  9.     public ProtocolSignature getProtocolSignature(String protocol, long clientVersion, int clientMethodsHash)  
  10.             throws IOException {  
  11.         return new ProtocolSignature(TestProtocol.versionID, null);  
  12.     }  
  13.   
  14.     @Override  
  15.     public String echo(String msg) {  
  16.         return msg;  
  17.     }  
  18. }  
Java代码
  1. public class RPCTest {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Configuration conf = new Configuration();  
  5.         Server server = startServer(conf);  
  6.         echo(conf, server);  
  7.     }  
  8.           
  9.         //构造RPC Client 并发送RPC 请求  
  10.     private static void echo(Configuration conf, Server server) {  
  11.         try {  
  12.             TestProtocol proxy = (TestProtocol) RPC.getProxy(TestProtocol.class, TestProtocol.versionID,  
  13.                     server.getListenerAddress(), conf);  
  14.             System.err.println(proxy.echo("hello world!!!"));  
  15.             server.stop();  
  16.         } catch (Exception e) {  
  17.             throw new Error(e);  
  18.         }  
  19.     }  
  20.   
  21.         //构造并启动RPC Server  
  22.     private static Server startServer(Configuration conf) {  
  23.         try {  
  24.             Server server = new RPC.Builder(conf).setProtocol(TestProtocol.class).setInstance(new TestProtocolImpl())  
  25.                     .setBindAddress("127.0.0.1").setPort(0).setNumHandlers(5).build();  
  26.             server.start();  
  27.             return server;  
  28.         } catch (Exception e) {  
  29.             throw new Error(e);  
  30.         }  
  31.     }  
  32. }  

    三.RPC类详解

    Hadoop RPC 内部实现位于源代码目录中hadoop-common-project/hadoop-common/src/main/java 下的org.apache.hadoop.ipc 包中, 而YARN 对RPC 的Protocol Buffers 封装则位于hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java 目录下的org.apache.hadoop.yarn.ipc 包中。

    3.1 rpc

hadoop的rpc序列化有protocol buffers和自带的writable,默认为writable实现。rpc采用java动态代理完成对远程方法的调用,即客户端在RpcInvocationHandler的invoke中将函数的调用信息(函数名,函数参数等)打包成Invocation发送到服务端,服务端收到调用信息后解析函数调用信息,通过反射完成函数的调用后返回给客户端。

   3.2 client

    client包含Call和Connection两个大类。当动态代理调用client的call方式时,创建Call,创建Connection,将Call放入Connection的hash表calls中,调用sendRpcRequest方法发送调用信息,并异步通过receiveRpcResponse接收消息将对于Call的状态改为done并将其移除calls。client检查Call的状态,当Call的状态为done时返回消息。

    3.3server

    listener的selector对象注册SelectionKey.OP_ACCEPT事件,接收到请求后轮询选择reader,reader的readSelector监听SelectionKey.OP_READ事件,将接收到的请求转成call放入server的callQueue中。server的handlers数据循环从callQueue取出call执行函数调用,调用完后将将结果返回给客户端,当数据不能一次返回时使用responder线程异步发送未完成的结果。

    一个Server只有一个listener和responder,reader的数量由ipc.server.read.threadpool.size配置,默认1个。

   四.yarn rpc

   yarn rpc是基于hadoop rpc且采用protocol buffers序列化框架的通信协议。

     应用实例以ResourceTracker的为例:

    

协议接口代码
  1. package org.apache.hadoop.yarn.server.api;  
  2. public interface ResourceTracker {  
  3.     
  4.   @Idempotent  
  5.   public RegisterNodeManagerResponse registerNodeManager(  
  6.       RegisterNodeManagerRequest request) throws YarnException,  
  7.       IOException;  
  8.   
  9.   @AtMostOnce  
  10.   public NodeHeartbeatResponse nodeHeartbeat(NodeHeartbeatRequest request)  
  11.       throws YarnException, IOException;  
  12.   
  13. }  

 

Rpcserverfactorypbimpl代码
  1. //RpcServerFactoryPBImpl的包名为协议接口的包名加.impl.pb.service  
  2. package org.apache.hadoop.yarn.server.api.impl.pb.service;  
  3. //RpcServerFactoryPBImpl的类名为协议接口名加PBServiceImpl  
  4. public class ResourceTrackerPBServiceImpl implements ResourceTrackerPB {  
  5.   
  6.   private ResourceTracker real;  
  7.     
  8.   public ResourceTrackerPBServiceImpl(ResourceTracker impl) {  
  9.     this.real = impl;  
  10.   }  
  11.   ....  
  12. }  

 

Rpcclientfactorypbimp❑代码
  1. //RpcClientFactoryPBImp的包名为协议接口的包名加.impl.pb.client  
  2. package org.apache.hadoop.yarn.server.api.impl.pb.client;  
  3. //RpcClientFactoryPBImp的类名为协议接口名加PBClientImpl  
  4. public class ResourceTrackerPBClientImpl implements ResourceTracker, Closeable {  
  5.   
  6. private ResourceTrackerPB proxy;  
  7.     
  8.   public ResourceTrackerPBClientImpl(long clientVersion, InetSocketAddress addr, Configuration conf) throws IOException {  
  9.     RPC.setProtocolEngine(conf, ResourceTrackerPB.class, ProtobufRpcEngine.class);  
  10.     proxy = (ResourceTrackerPB)RPC.getProxy(  
  11.         ResourceTrackerPB.class, clientVersion, addr, conf);  
  12.   }  
  13.   ```  
  14. }  

 

Java代码
  1. package org.apache.hadoop.yarn.server.resourcemanager;  
  2. public class ResourceTrackerService extends AbstractService implements  
  3.     ResourceTracker {  
  4.   
  5.      protected void serviceStart() throws Exception {  
  6.          super.serviceStart();  
  7.          Configuration conf = getConfig();  
  8.          YarnRPC rpc = YarnRPC.create(conf);  
  9.          this.server =  
  10.             rpc.getServer(ResourceTracker.classthis, resourceTrackerAddress,  
  11.           conf, null,  
  12.         conf.getInt(YarnConfiguration.RM_RESOURCE_TRACKER_CLIENT_THREAD_COUNT,   
  13.               YarnConfiguration.DEFAULT_RM_RESOURCE_TRACKER_CLIENT_THREAD_COUNT));  
  14.           ````  
  15.      }  
  16.   
  17.      public RegisterNodeManagerResponse registerNodeManager(  
  18.       RegisterNodeManagerRequest request) throws YarnException,  
  19.       IOException{  
  20.         ````  
  21.      }  
  22.   
  23.      public NodeHeartbeatResponse nodeHeartbeat(NodeHeartbeatRequest request)  
  24.       throws YarnException, IOException{  
  25.          ````  
  26.      }  
  27. }  

 

Java代码
  1. package org.apache.hadoop.yarn.server.nodemanager;  
  2. public class NodeStatusUpdaterImpl extends AbstractService implements  
  3.     NodeStatusUpdater {  
  4.     private ResourceTracker resourceTracker;  
  5.       
  6.     @Override  
  7.     protected void serviceStart() throws Exception {  
  8.   
  9.       // NodeManager is the last service to start, so NodeId is available.  
  10.       this.nodeId = this.context.getNodeId();  
  11.       this.httpPort = this.context.getHttpPort();  
  12.       this.nodeManagerVersionId = YarnVersionInfo.getVersion();  
  13.       try {  
  14.         // Registration has to be in start so that ContainerManager can get the  
  15.         // perNM tokens needed to authenticate ContainerTokens.  
  16.         this.resourceTracker = getRMClient();  
  17.         registerWithRM();  
  18.         super.serviceStart();  
  19.         startStatusUpdater();  
  20.       } catch (Exception e) {  
  21.         String errorMessage = "Unexpected error starting NodeStatusUpdater";  
  22.         LOG.error(errorMessage, e);  
  23.         throw new YarnRuntimeException(e);  
  24.       }}  
  25.   
  26.      protected ResourceTracker getRMClient() throws IOException {  
  27.         Configuration conf = getConfig();  
  28.        return ServerRMProxy.createRMProxy(conf, ResourceTracker.class);  
  29.     }  
  30. }  

 

Java代码
  1. public class RMProxy<T> {  
  2.    @Private  
  3.   static <T> T getProxy(final Configuration conf,  
  4.       final Class<T> protocol, final InetSocketAddress rmAddress)  
  5.       throws IOException {  
  6.     return UserGroupInformation.getCurrentUser().doAs(  
  7.       new PrivilegedAction<T>() {  
  8.         @Override  
  9.         public T run() {  
  10.           return (T) YarnRPC.create(conf).getProxy(protocol, rmAddress, conf);  
  11.         }  
  12.       });  
  13.   }  
  14.   ```  
  15. }  
 
0 0
原创粉丝点击