Hadoop学习笔记—3.Hadoop RPC机制的使用
一、RPC基础概念
1.1 RPC的基础概念
RPC,即Remote Procdure Call,中文名:远程过程调用;
(1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网络通信细节,对我们来说是透明的。因此,它经常用于分布式网络通信中。
RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
(2)Hadoop的进程间交互都是通过RPC来进行的,比如Namenode与Datanode直接,Jobtracker与Tasktracker之间等。
因此,可以说:Hadoop的运行就是建立在RPC基础之上的。
1.2 RPC的显著特点
(1)透明性:远程调用其他机器上的程序,对用户来说就像是调用本地方法一样;
(2)高性能:RPC Server能够并发处理多个来自Client的请求;
(3)可控性:jdk中已经提供了一个RPC框架—RMI,但是该PRC框架过于重量级并且可控之处比较少,所以Hadoop RPC实现了自定义的PRC框架。
1.3 RPC的基本流程
(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的方法,也能返回值。
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)启动服务端,开始监听客户端请求
(2)启动客户端,开始向服务端发请求
(3)查看服务端状态,是否被调用
SUMMARY:从上面的RPC调用中,可以看出:在客户端调用的业务类的方法是定义在业务类的接口中的。该接口实现了VersionedProtocal接口。
(4)现在我们在命令行执行jps命令,查看输出信息,会出现如下图所示的:
从上图中可以看到一个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
Hadoop学习笔记—3.Hadoop RPC机制的使用的更多相关文章
- [转帖]hadoop学习笔记:hadoop文件系统浅析
hadoop学习笔记:hadoop文件系统浅析 https://www.cnblogs.com/sharpxiajun/archive/2013/06/15/3137765.html 1.什么是分布式 ...
- Hadoop学习笔记【Hadoop家族成员概述】
Hadoop家族成员概述 一.Hadoop简介 1.1 什么是Hadoop? Hadoop是一个分布式系统基础架构,由Apache基金会所开发,目前Yahoo!是其最重要的贡献者. Hadoop实现了 ...
- [Hadoop] Hadoop学习笔记之Hadoop基础
1 Hadoop是什么? Google公司发表了两篇论文:一篇论文是“The Google File System”,介绍如何实现分布式地存储海量数据:另一篇论文是“Mapreduce:Simplif ...
- Hadoop学习笔记(3) Hadoop文件系统二
1 查询文件系统 (1) 文件元数据:FileStatus,该类封装了文件系统中文件和目录的元数据,包括文件长度.块大小.备份.修改时间.所有者以及版权信息.FileSystem的getFileSta ...
- Hadoop学习笔记(3) Hadoop文件系统一
1. 分布式文件系统,即为管理网络中跨多台计算机存储的文件系统.HDFS以流式数据访问模式来存储超大文件,运行于商用硬件集群上.HDFS的构建思路为:一次写入.多次读取是最高效的访问模式.数据集通常由 ...
- 吴裕雄--天生自然HADOOP学习笔记:hadoop集群实现PageRank算法实验报告
实验课程名称:大数据处理技术 实验项目名称:hadoop集群实现PageRank算法 实验类型:综合性 实验日期:2018年 6 月4日-6月14日 学生姓名 吴裕雄 学号 15210120331 班 ...
- 吴裕雄--天生自然Hadoop学习笔记:Hadoop简介
Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储.Hadoop实现了一个分布式文件系统(H ...
- Hadoop学习笔记—6.Hadoop Eclipse插件的使用
开篇:Hadoop是一个强大的并行软件开发框架,它可以让任务在分布式集群上并行处理,从而提高执行效率.但是,它也有一些缺点,如编码.调试Hadoop程序的难度较大,这样的缺点直接导致开发人员入门门槛高 ...
- Hadoop学习笔记(3) Hadoop I/O
1. HDFS的数据完整性 HDFS会对写入的所有数据计算校验和,并在读取数据时验证校验和.datanode负责在验证收到的数据后存储数据及其校验和.正在写数据的客户端将数据及其校验和发送到由一系列d ...
随机推荐
- 一次mongodb 统计需求
需求: 临下班运营的同事发来了一个需求,要统计数据库里某个collection的所有document 中某个字段(_id)出现的次数._id 字段的范围是0-4000. 假设collection 是这 ...
- ssh反向连接和简单实现
转自:http://blog.chinaunix.net/uid-20109107-id-2954579.html SSH反向连接的使用 1.什么是反向连接?反向连接是指主机A(受控端)主动连接主机B ...
- XSS之xssprotect(转)
参考资料 1 跨网站脚本 http://zh.wikipedia.org/wiki/XSS 2 http://code.google.com/p/xssprotect/ 一 跨网站脚本介绍 ...
- SpringMVC(一) SpringMVC概述
SpringMVC为展现层提供的基于MVC设计理念的优秀的WEB框架,是目前主流的MVC框架之一.Spring 3.0之后,超越Struts2成为最优秀的MVC框架. SpringMVC通过一套MVC ...
- Swift 基本常量和变量,基本数据类型
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #4dbf56 } p.p2 { margin: 0.0px 0. ...
- Linux中安装NodeJs 、cnpm 、npm
一.安装NodeJs 切换到 cd /usr/local/src/ 下载nodejs wget https://nodejs.org/dist/v6.9.3/node-v6.9.3-linux-x64 ...
- js判断当前页面在移动设备还是在PC端中打开
方法一: var isPC = function () { var userAgentInfo = navigator.userAgent.toLowerCase(); var Agents = ne ...
- IO(1)
java的IO主要在java.io包下,包括字节流和字符流. 1 File File类可以对文件和目录进行操作,就是不能访问文件本身,其常用方法包括: 1)String getName(),返回fil ...
- Lua 排行榜更新
排行榜: key:玩家名字,val:玩家的数值 local key1 = {"a1", "a2", "b1", "b2" ...
- 解决ugui中Image使用iTween的ColorTo、ColorFrom等不生效
查看iTween的源码找到ColorFrom函数,看该函数的注释“/// Changes a GameObject's color values instantly then returns them ...