Hadoop-远程过程调用

Hadoop IPC类图如下


 
 

 

连接

  1. <span style="font-size: 14px;">//为了提高通讯效率,连接是可以复用的,通过ConnectionId来区分不同的连接  
  2. class ConnectionId {  
  3.      InetSocketAddress address;         //远端服务器的地址  
  4.      UserGroupInformation ticket;       //用户和用户组的信息  
  5.      Class<?> protocol;                     //IPC接口对应的类对象  
  6. }  
  7.   
  8. //</span>ConnectionHeader类是客户端和服务端TCP连接建立之后交换的第一条消息,包括ConnectionId中的  
  9. <span style="font-size: 14px;">//用户信息和IPC接口信息,用于确认用户是否有权利连接  
  10. </span>ConnectionHeader  
  11.   
  12.   
  13. //服务端连接对象  
  14. public class Connection {  
  15.     private boolean rpcHeaderRead = false//是否已读如入了RPC版本号  
  16.     private boolean headerRead = false;  //是否读入了连接消息头  
  17.   
  18.     private SocketChannel channel;  
  19.     private ByteBuffer data;  
  20.     private ByteBuffer dataLengthBuffer;  
  21.     private LinkedList<Call> responseQueue;  
  22.     private volatile int rpcCount = 0//当前正在处理的RPC数量  
  23.     private long lastContact;  
  24.     private int dataLength;  
  25.     private Socket socket;  
  26.     // Cache the remote host & port info so that even if the socket is   
  27.     // disconnected, we can say where it used to connect to.  
  28.     private String hostAddress;  
  29.     private int remotePort;  
  30.     private InetAddress addr;  
  31.       
  32.     ConnectionHeader header = new ConnectionHeader();  
  33.     Class<?> protocol;  
  34.     boolean useSasl;  
  35.     SaslServer saslServer;  
  36.     private AuthMethod authMethod;  
  37.     private boolean saslContextEstablished;  
  38.     private boolean skipInitialSaslHandshake;  
  39.     private ByteBuffer rpcHeaderBuffer;  
  40.     private ByteBuffer unwrappedData;  
  41.     private ByteBuffer unwrappedDataLengthBuffer;  
  42.     UserGroupInformation user = null;  
  43. }  
  44.   
  45. //客户端连接  
  46.   private class Connection extends Thread {  
  47.     private InetSocketAddress server;             //IPC服务端地址  
  48.     private String serverPrincipal;  // server's krb5 principal name  
  49.     private ConnectionHeader header;              //连接消息头  
  50.     private final ConnectionId remoteId;                //IPC连接标识  
  51.     private AuthMethod authMethod; // authentication method  
  52.     private boolean useSasl;  
  53.     private Token<? extends TokenIdentifier> token;  
  54.     private SaslRpcClient saslRpcClient;  
  55.       
  56.     private Socket socket = null;                 // connected socket  
  57.     private DataInputStream in;  
  58.     private DataOutputStream out;  
  59.     private int rpcTimeout;  
  60.     private int maxIdleTime; //connections will be culled if it was idle for  
  61.          //maxIdleTime msecs  
  62.     private int maxRetries; //the max. no. of retries for socket connections  
  63.     private boolean tcpNoDelay; // if T then disable Nagle's Algorithm  
  64.     private int pingInterval; // how often sends ping to the server in msecs  
  65.       
  66.     // currently active calls  
  67.     private Hashtable<Integer, Call> calls = new Hashtable<Integer, Call>();  
  68.     private AtomicLong lastActivity = new AtomicLong();// last I/O activity time  
  69.     private AtomicBoolean shouldCloseConnection = new AtomicBoolean();  // indicate if the connection is closed  
  70.     private IOException closeException; // close reason  
  71. }  

 

Call

  1. //客户端  
  2.   private class Call {  
  3.     int id;                                       // call id  
  4.     Writable param;                               // parameter  
  5.     Writable value;                               // value, null if error  
  6.     IOException error;                            // exception, null if value  
  7.     boolean done;      
  8. }  
  9.   
  10. //服务端  
  11.   private static class Call {  
  12.     private int id;                               // the client's call id  
  13.     private Writable param;                       // the parameter passed  
  14.     private Connection connection;                // connection to client  
  15.     private long timestamp;   
  16. }  
  17.   
  18. //客户端和服务端通过各自的Call对象发送调用  
  19. 客户端还有ParallelCall 用于同时发送多个远程IPC调用  

 

 

服务端处理

  1. //处理监听事件的线程  
  2. class Listener extends Thread {  
  3.     //创建SeverSocketChannel,并注册ACCEPT事件  
  4.     public Listener() {  
  5.         acceptChannel = ServerSocketChannel.open();   
  6.         acceptChannel.configureBlocking(false);  
  7.   
  8.         // Bind the server socket to the local host and port  
  9.         bind(acceptChannel.socket(), address, backlogLength);  
  10.         port = acceptChannel.socket().getLocalPort(); //Could be an ephemeral port  
  11.         // create a selector;  
  12.         selector= Selector.open();  
  13.         readers = new Reader[readThreads];  
  14.         readPool = Executors.newFixedThreadPool(readThreads);  
  15.         for (int i = 0; i < readThreads; i++) {  
  16.             Selector readSelector = Selector.open();  
  17.             Reader reader = new Reader(readSelector);  
  18.             readers[i] = reader;  
  19.             readPool.execute(reader);  
  20.         }  
  21.         acceptChannel.register(selector, SelectionKey.OP_ACCEPT);     
  22.     }  
  23.   
  24.     //处理ACCEPT事件  
  25.     public void run() {  
  26.     selector.select();  
  27.     Iterator<SelectionKey> iter = selector.selectedKeys().iterator();  
  28.     while (iter.hasNext()) {  
  29.         key = iter.next();  
  30.         iter.remove();  
  31.         if (key.isValid()) {  
  32.             if (key.isAcceptable())  
  33.                 doAccept(key);  
  34.             }  
  35.         }                 
  36.     }  
  37.   
  38. }  
  39.   
  40. //Reader线程,用于处理读事件并交由Handler线程处理  
  41. class Reader implements Runnable {  
  42.     public void run() {  
  43.         readSelector.select();  
  44.         while (adding) {  
  45.             this.wait(1000);  
  46.         }  
  47.         Iterator<SelectionKey> iter = readSelector.selectedKeys().iterator();  
  48.         while (iter.hasNext()) {  
  49.             key = iter.next();  
  50.             iter.remove();  
  51.             if (key.isValid()) {  
  52.                 if (key.isReadable()) {  
  53.                     doRead(key);  
  54.                 }  
  55.             }  
  56.         }                         
  57.     }  
  58. }  
  59.   
  60. //异步的处理写事件  
  61. class Responder extends Thread {  
  62.     public void run() {  
  63.         waitPending();     // If a channel is being registered, wait.  
  64.         writeSelector.select(PURGE_INTERVAL);  
  65.         Iterator<SelectionKey> iter = writeSelector.selectedKeys().iterator();  
  66.         while (iter.hasNext()) {  
  67.             SelectionKey key = iter.next();  
  68.             iter.remove();  
  69.             if (key.isValid() && key.isWritable()) {  
  70.                 doAsyncWrite(key);  
  71.             }              
  72.         }  
  73.           
  74.         synchronized (writeSelector.keys()) {  
  75.             calls = new ArrayList<Call>(writeSelector.keys().size());  
  76.             iter = writeSelector.keys().iterator();  
  77.             while (iter.hasNext()) {  
  78.                 SelectionKey key = iter.next();  
  79.                 Call call = (Call)key.attachment();  
  80.                 if (call != null && key.channel() == call.connection.channel) {   
  81.                     calls.add(call);  
  82.                 }  
  83.             }  
  84.         }         
  85.     }  
  86.   
  87. }  
  88.   
  89.   
  90.   
  91. void doAsyncWrite(SelectionKey key) {  
  92.     synchronized(call.connection.responseQueue) {  
  93.         processResponse(call.connection.responseQueue, false);  
  94.     }  
  95. }  
  96.   
  97.   
  98. //inHandler用于表示是Handler中直接调用写操作  
  99. //还是Responer线程的异步写操作  
  100. void processResponse(LinkedList<Call> responseQueue,boolean inHandler) {  
  101.     call = responseQueue.removeFirst();  
  102.           SocketChannel channel = call.connection.channel;  
  103.     int count =  (buffer.remaining() <= NIO_BUFFER_LIMIT) ?  
  104.                  channel.write(buffer) : channelIO(null, channel, buffer);            
  105. }  
  106.   
  107.   
  108. void doRead(SelectionKey key) {  
  109.     Connection c = (Connection)key.attachment();  
  110.     count = c.readAndProcess();  
  111. }  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值