Hadoop学习笔记—3.Hadoop RPC机制、原理及使用
2016-09-18 11:31
561 查看
一、RPC基础概念
1.1 RPC的基础概念
RPC,即Remote Procdure Call,中文名:远程过程调用;(1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网络通信细节,对我们来说是透明的。因此,它经常用于分布式网络通信中。
RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
(2)Hadoop的进程间交互都是通过RPC来进行的,比如Namenode与Datanode直接,Jobtracker与Tasktracker之间等。
![](http://images.cnitblog.com/blog/381412/201502/111215143542709.jpg)
因此,可以说:Hadoop的运行就是建立在RPC基础之上的。
1.2 RPC的显著特点
(1)透明性:远程调用其他机器上的程序,对用户来说就像是调用本地方法一样;(2)高性能:RPC Server能够并发处理多个来自Client的请求;
(3)可控性:jdk中已经提供了一个RPC框架—RMI,但是该PRC框架过于重量级并且可控之处比较少,所以Hadoop RPC实现了自定义的PRC框架。
1.3 RPC的基本流程
![](http://images.cnitblog.com/blog/381412/201502/111227284643833.png)
(1)RPC采用了C/S的模式;
(2)Client端发送一个带有参数的请求信息到Server;
(3)Server接收到这个请求以后,根据发送过来的参数调用相应的程序,然后把自己计算好的结果发送给Client端;
(4)Client端接收到结果后继续运行;
1.4 Hadoop中的RPC机制
同其他RPC框架一样,Hadoop RPC分为四个部分:(1)序列化层:Clent与Server端通信传递的信息采用了Hadoop里提供的序列化类或自定义的Writable类型;
(2)函数调用层:Hadoop RPC通过动态代理以及java反射实现函数调用;
(3)网络传输层:Hadoop RPC采用了基于TCP/IP的socket机制;
(4)服务器端框架层:RPC Server利用java NIO以及采用了事件驱动的I/O模型,提高RPC Server的并发处理能力;
Hadoop RPC在整个Hadoop中应用非常广泛,Client、DataNode、NameNode之间的通讯全靠它了。例如:我们平时操作HDFS的时候,使用的是FileSystem类,它的内部有个DFSClient对象,这个对象负责与NameNode打交道。在运行时,DFSClient在本地创建一个NameNode的代理,然后就操作这个代理,这个代理就会通过网络,远程调用到NameNode的方法,也能返回值。
![](http://images.cnitblog.com/blog/381412/201502/111231587613790.jpg)
1.5 Hadoop RPC设计技术
(1)动态代理About:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,代理对象对客户隐藏了实际对象。目前Java开发包中提供了对动态代理的支持,但现在只支持对接口的实现。
(2)反射——动态加载类
(3)序列化
(4)非阻塞的异步IO(NIO)
Java NIO原理请参考阅读:http://weixiaolu.iteye.com/blog/1479656
二、如何使用RPC
2.1 Hadoop 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接口)实例构造一个服务器对象,用于处理客户端发送的请求。
2.2 使用Hadoop RPC的四大步凑
(1)定义RPC协议RPC协议是客户端和服务器端之间的通信接口,它定义了服务器端对外提供的服务接口。
(2)实现RPC协议
Hadoop RPC协议通常是一个Java接口,用户需要实现该接口。
(3)构造和启动RPC SERVER
直接使用静态类Builder构造一个RPC Server,并调用函数start()启动该Server。
(4)构造RPC Client并发送请求
使用静态方法getProxy构造客户端代理对象,直接通过代理对象调用远程端的方法。
三、RPC应用实例
3.1 定义RPC协议
如下所示,我们定义一个IProxyProtocol 通信接口,声明了一个Add()方法。public interface IProxyProtocol extends VersionedProtocol { static final long VERSION = 23234L; //版本号,默认情况下,不同版本号的RPC Client和Server之间不能相互通信 int Add(int number1,int number2); }
需要注意的是:
(1)Hadoop中所有自定义RPC接口都需要继承VersionedProtocol接口,它描述了协议的版本信息。
(2)默认情况下,不同版本号的RPC Client和Server之间不能相互通信,因此客户端和服务端通过版本号标识。
3.2 实现RPC协议
Hadoop RPC协议通常是一个Java接口,用户需要实现该接口。对IProxyProtocol接口进行简单的实现如下所示:public class MyProxy implements IProxyProtocol { public int Add(int number1,int number2) { System.out.println("我被调用了!"); int result = number1+number2; return result; } public long getProtocolVersion(String protocol, long clientVersion) throws IOException { System.out.println("MyProxy.ProtocolVersion=" + IProxyProtocol.VERSION); // 注意:这里返回的版本号与客户端提供的版本号需保持一致 return IProxyProtocol.VERSION; } }
这里实现的Add方法很简单,就是一个加法操作。为了查看效果,这里通过控制台输出一句:“我被调用了!”
3.3 构造RPC Server并启动服务
这里通过RPC的静态方法getServer来获得Server对象,如下代码所示:public class MyServer { public static int PORT = 5432; public static String IPAddress = "127.0.0.1"; public static void main(String[] args) throws Exception { MyProxy proxy = new MyProxy(); final Server server = RPC.getServer(proxy, IPAddress, PORT, new Configuration()); server.start(); } }
这段代码的核心在于第5行的RPC.getServer方法,该方法有四个参数,第一个参数是被调用的java对象,第二个参数是服务器的地址,第三个参数是服务器的端口 。获得服务器对象后,启动服务器。这样,服务器就在指定端口监听客户端的请求。到此为止,服务器就处于监听状态,不停地等待客户端请求到达。
3.4 构造RPC Client并发出请求
这里使用静态方法getProxy或waitForProxy构造客户端代理对象,直接通过代理对象调用远程端的方法,具体如下所示:public class MyClient { public static void main(String[] args) { InetSocketAddress inetSocketAddress = new InetSocketAddress( MyServer.IPAddress, MyServer.PORT); try { // 注意:这里传入的版本号需要与代理保持一致 IProxyProtocol proxy = (IProxyProtocol) RPC.waitForProxy( IProxyProtocol.class, IProxyProtocol.VERSION, inetSocketAddress, new Configuration()); int result = proxy.Add(10, 25); System.out.println("10+25=" + result); RPC.stopProxy(proxy); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
以上代码中核心在于RPC.waitForProxy(),该方法有四个参数,第一个参数是被调用的接口类,第二个是客户端版本号,第三个是服务端地址。返回的代理对象,就是服务端对象的代理,内部就是使用java.lang.Proxy实现的。
经过以上四步,我们便利用Hadoop RPC搭建了一个非常高效的客户机–服务器网络模型。
3.5 查看运行结果
(1)启动服务端,开始监听客户端请求![](http://images.cnitblog.com/blog/381412/201502/111400402141589.jpg)
(2)启动客户端,开始向服务端发请求
![](http://images.cnitblog.com/blog/381412/201502/111401416513785.jpg)
(3)查看服务端状态,是否被调用
![](http://images.cnitblog.com/blog/381412/201502/111402516511733.jpg)
SUMMARY:从上面的RPC调用中,可以看出:在客户端调用的业务类的方法是定义在业务类的接口中的。该接口实现了VersionedProtocal接口。
(4)现在我们在命令行执行jps命令,查看输出信息,会出现如下图所示的:
![](http://images.cnitblog.com/blog/381412/201502/111406041673819.jpg)
从上图中可以看到一个java进程,是“MyServer”,该进程正是我们刚刚运行的RPC的服务端类MyServer。因此,大家可以联想到我们搭建Hadoop环境时,也执行过该命令用来判断Hadoop的相关进程是否全部启动。
SUMMARY:那么可以判断,Hadoop启动时产生的5个java进程也应该是RPC的服务端。
下面我们观察NameNode的源代码,如下图所示,可以看到NameNode确实创建了RPC的服务端。
private void initialize(Configuration conf) throws IOException { ...... // create rpc server InetSocketAddress dnSocketAddr = getServiceRpcServerAddress(conf); if (dnSocketAddr != null) { int serviceHandlerCount = conf.getInt(DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_KEY, DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_DEFAULT); this.serviceRpcServer = RPC.getServer(this, dnSocketAddr.getHostName(), dnSocketAddr.getPort(), serviceHandlerCount, false, conf, namesystem.getDelegationTokenSecretManager()); this.serviceRPCAddress = this.serviceRpcServer.getListenerAddress(); setRpcServiceServerAddress(conf); } this.server = RPC.getServer(this, socAddr.getHostName(), socAddr.getPort(), handlerCount, false, conf, namesystem .getDelegationTokenSecretManager()); ...... }
参考资料
(1)thomas0yang,《Hadoop RPC框架》:http://blog.csdn.net/thomas0yang/article/details/41211259(2)姜维,《Hadoop RPC机制分析》:http://blog.csdn.net/jiangwei0910410003/article/details/21155911 (此文从源码角度分析了RPC,想要深入了解的可以阅读此文)
(3)吴超,《Hadoop的底层架构—RPC机制》:http://www.superwu.cn/2013/08/05/360
(4)东苑草根,《Hadoop RPC基础》:http://www.cnblogs.com/dycg/p/rpc.html
(5)Suddenly,《Hadoop日记Day10-RPC机制》:http://www.cnblogs.com/sunddenly/p/3983193.html
(6)董西成,《Hadoop RPC使用方法》:http://book.51cto.com/art/201312/422043.htm
作者:周旭龙
出处:http://edisonchou.cnblogs.com/
相关文章推荐
- Hadoop学习笔记—3.Hadoop RPC机制的使用
- Hadoop学习笔记—3.Hadoop RPC机制的使用
- Hadoop学习笔记—3.Hadoop RPC机制的使用
- Hadoop学习笔记—3.Hadoop RPC机制的使用
- Hadoop学习笔记—3.Hadoop RPC机制的使用
- Hadoop RPC机制的使用(笔记3)
- 【D3D11游戏编程】学习笔记十八:模板缓冲区的使用、镜子的实现--模板缓冲实现原理和机制
- hadoop学习笔记3.通过电话通信清单例子简单使用Reduce和打包JAR
- Hadoop 学习之RPC的使用与实现原理
- Hadoop学习笔记(八):如何使用Maven构建《hadoop权威指南3》随书的源码包
- 【hadoop】Hadoop学习笔记(六):Hadoop读写文件时内部工作机制
- Hadoop学习笔记(六):Hadoop读写文件时内部工作机制
- 【hadoop】Hadoop学习笔记(八):如何使用Maven构建《hadoop权威指南3》随书的源码包
- C# Hadoop学习笔记(八)—C#的分布式计算机制
- 如何使用hadoop RPC机制
- 云计算学习笔记---Hadoop简介,hadoop实现原理,NoSQL介绍...与传统关系型数据库对应关系,云计算面临的挑战
- hadoop学习笔记-HDFS原理
- Java学习笔记之垃圾收集机制和原理
- 【hadoop】Hadoop学习笔记(七):使用distcp并行拷贝大数据文件
- 云计算学习笔记---Hadoop简介,hadoop实现原理,NoSQL介绍...与传统关系型数据库对应关系,云计算面临的挑战