Hadoop中的RPC应用实例1

hadoop作为分布式的系统, 集群机器之间的通信是最基本,最常见的需求。
这种需求本质上是IPC, 即进程间通信。 按照传统的UINX编程模型,进程间通信无非是如下的几种方式:
管道, FIFO, 消息队列, 信号量, 共享存储, 套接字。只有套接字是可以跨机器的网络通信, 能满足hadoop的需求。

通常情况下, 网络通信的程序使用显式网络编程(即直接使用java.net包)。比如Web浏览器, Web服务器等。
但也有另一部分程序使用隐式网络编程, 比如利用hadoop RPC这种封装了底层通信细节的工具包。

这样做使得底层的网络通信对于程序员透明。一则减轻了程序员的负担, 二则抽象了功能模块, 使得模块之间职责更清晰, 便于维护。

首先展示一个hadoop RPC功能demo, 了解hadoop RPC的用法。

step 1: 在pom.xml文件中添加依赖项

1
2
3
4
5
< dependency >
      < groupId >org.apache.hadoop</ groupId >
      < artifactId >hadoop-common</ artifactId >
      < version >2.6.0</ version >
  </ dependency >

step 2: 在src/main/resources中添加log4j.properties

1
2
3
4
5
6
7
8
9
log4j.rootLogger=DEBUG,console
log4j.additivity.org.apache=true
# (console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=INFO
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

step 3: 定义RPC协议

1
2
3
4
5
6
7
8
9
10
package  hadooprpc.demo;
 
import  java.io.IOException;
 
interface  ClientProtocol  extends  org.apache.hadoop.ipc.VersionedProtocol {
    // 版本号,默认情况下,不同版本号的 RPC Client 和 Server 之间不能相互通信
    public  static  final  long  versionID = 1L;
    String echo(String value)  throws  IOException;
    int  add( int  v1,  int  v2)  throws  IOException;
}

step 4: 实现RPC协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package  hadooprpc.demo;
 
import  java.io.IOException;
 
import  org.apache.hadoop.ipc.ProtocolSignature;
 
public   class  ClientProtocolImpl  implements  ClientProtocol {
     // 重载的方法,用于获取自定义的协议版本号,
    public  long  getProtocolVersion(String protocol,  long  clientVersion) {
       return  ClientProtocol.versionID;
    }
 
    // 重载的方法,用于获取协议签名
    public  ProtocolSignature getProtocolSignature(String protocol,  long  clientVersion,
    int  hashcode) {
       return  new  ProtocolSignature(ClientProtocol.versionID,  null );
    }
 
    public  String echo(String value)  throws  IOException {
       return  value;
    }
 
    public  int  add( int  v1,  int  v2)  throws  IOException {
       return  v1 + v2;
    }
}

step 5; 构造并启动 RPC Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package  hadooprpc.demo;
 
import  java.io.IOException;
 
import  org.apache.hadoop.HadoopIllegalArgumentException;
import  org.apache.hadoop.conf.Configuration;
import  org.apache.hadoop.ipc.RPC;
import  org.apache.hadoop.ipc.Server;
 
public  class  RPCServer {
    public  static  void  main(String[] args)  throws  HadoopIllegalArgumentException, IOException {
       Configuration conf =  new  Configuration();
       Server server =  new  RPC.Builder(conf).setProtocol(ClientProtocol. class )
             .setInstance( new  ClientProtocolImpl()).setBindAddress( "localhost" ).setPort( 8097 )
             .setNumHandlers( 5 ).build();
             server.start();
    }
}

step 6: 构造 RPC Client 并发送 RPC 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  hadooprpc.demo;
 
import  java.io.IOException;
import  java.net.InetSocketAddress;
 
import  org.apache.hadoop.conf.Configuration;
import  org.apache.hadoop.ipc.RPC;
 
public  class  RPCClient {
    public  static  void  main(String[] args)  throws  IOException {
       ClientProtocol client = (ClientProtocol)RPC.getProxy(ClientProtocol. class , ClientProtocol.versionID,
                                                            new  InetSocketAddress( 8097 ),  new  Configuration());
       int  result = client.add( 5 6 );
       System.out.println(result);
       String echoResult = client.echo( "result" );
       System.out.println(echoResult);
       RPC.stopProxy(client); -- 关闭连接
    }
}

step 7: 启动RPC Server, 然后执行 RPC Client.

通过上面的例子可以发现, 通过这种编程方式,不用考虑网络层的细节,只需要编写接口和接口实现即可。

hadoop RPC的实现原理很简单。
Client:
1. 通过动态代理,获取到调用接口的方法,参数类型。
2. 将调用信息编码,发送到服务器
3. 获取服务器的返回值, 并解码。
4. 返回调用方法的返回值。
Server:
1. 启动服务器, 并监听客户端。
2. 获取客户端发送过来的调用方法, 参数。
3. 执行实现类中相关的方法。
4. 将返回值发送到客户端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值