一、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()方法。

  1. public interface IProxyProtocol extends VersionedProtocol {
  2. static final long VERSION = 23234L; //版本号,默认情况下,不同版本号的RPC Client和Server之间不能相互通信
  3. int Add(int number1,int number2);
  4. }

  需要注意的是:

  (1)Hadoop中所有自定义RPC接口都需要继承VersionedProtocol接口,它描述了协议的版本信息。

  (2)默认情况下,不同版本号的RPC Client和Server之间不能相互通信,因此客户端和服务端通过版本号标识。

3.2 实现RPC协议

  Hadoop RPC协议通常是一个Java接口,用户需要实现该接口。对IProxyProtocol接口进行简单的实现如下所示:

  1. public class MyProxy implements IProxyProtocol {
  2. public int Add(int number1,int number2) {
  3. System.out.println("我被调用了!");
  4. int result = number1+number2;
  5. return result;
  6. }
  7.  
  8. public long getProtocolVersion(String protocol, long clientVersion)
  9. throws IOException {
  10. System.out.println("MyProxy.ProtocolVersion=" + IProxyProtocol.VERSION);
  11. // 注意:这里返回的版本号与客户端提供的版本号需保持一致
  12. return IProxyProtocol.VERSION;
  13. }
  14. }

  这里实现的Add方法很简单,就是一个加法操作。为了查看效果,这里通过控制台输出一句:“我被调用了!”

3.3 构造RPC Server并启动服务

  这里通过RPC的静态方法getServer来获得Server对象,如下代码所示:

  1. public class MyServer {
  2. public static int PORT = 5432;
  3. public static String IPAddress = "127.0.0.1";
  4.  
  5. public static void main(String[] args) throws Exception {
  6. MyProxy proxy = new MyProxy();
  7. final Server server = RPC.getServer(proxy, IPAddress, PORT, new Configuration());
  8. server.start();
  9. }
  10. }

  这段代码的核心在于第5行的RPC.getServer方法,该方法有四个参数,第一个参数是被调用的java对象,第二个参数是服务器的地址,第三个参数是服务器的端口 。获得服务器对象后,启动服务器。这样,服务器就在指定端口监听客户端的请求。到此为止,服务器就处于监听状态,不停地等待客户端请求到达。

3.4 构造RPC Client并发出请求

  这里使用静态方法getProxy或waitForProxy构造客户端代理对象,直接通过代理对象调用远程端的方法,具体如下所示:

  1. public class MyClient {
  2.  
  3. public static void main(String[] args) {
  4. InetSocketAddress inetSocketAddress = new InetSocketAddress(
  5. MyServer.IPAddress, MyServer.PORT);
  6.  
  7. try {
  8. // 注意:这里传入的版本号需要与代理保持一致
  9. IProxyProtocol proxy = (IProxyProtocol) RPC.waitForProxy(
  10. IProxyProtocol.class, IProxyProtocol.VERSION, inetSocketAddress,
  11. new Configuration());
  12. int result = proxy.Add(10, 25);
  13. System.out.println("10+25=" + result);
  14.  
  15. RPC.stopProxy(proxy);
  16. } catch (IOException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. }
  20. }
  21.  
  22. }

  以上代码中核心在于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的服务端。

  1. private void initialize(Configuration conf) throws IOException {
  2. ......
  3. // create rpc server
  4. InetSocketAddress dnSocketAddr = getServiceRpcServerAddress(conf);
  5. if (dnSocketAddr != null) {
  6. int serviceHandlerCount =
  7. conf.getInt(DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_KEY,
  8. DFSConfigKeys.DFS_NAMENODE_SERVICE_HANDLER_COUNT_DEFAULT);
  9. this.serviceRpcServer = RPC.getServer(this, dnSocketAddr.getHostName(),
  10. dnSocketAddr.getPort(), serviceHandlerCount,
  11. false, conf, namesystem.getDelegationTokenSecretManager());
  12. this.serviceRPCAddress = this.serviceRpcServer.getListenerAddress();
  13. setRpcServiceServerAddress(conf);
  14. }
  15. this.server = RPC.getServer(this, socAddr.getHostName(),
  16. socAddr.getPort(), handlerCount, false, conf, namesystem
  17. .getDelegationTokenSecretManager());
  18. ......
  19. }

欢迎各位来探讨交流:QQ:747861092

QQ群:163354117    (群名称:CodeForFuture)

每天收获一点点------Hadoop RPC机制的使用的更多相关文章

  1. Hadoop学习笔记—3.Hadoop RPC机制的使用

    一.RPC基础概念 1.1 RPC的基础概念 RPC,即Remote Procdure Call,中文名:远程过程调用: (1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网 ...

  2. Hadoop RPC机制的使用

    一.RPC基础概念 1.1 RPC的基础概念 RPC,即Remote Procdure Call,中文名:远程过程调用: (1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网 ...

  3. Hadoop RPC机制详解

    网络通信模块是分布式系统中最底层的模块,他直接支撑了上层分布式环境下复杂的进程间通信逻辑,是所有分布式系统的基础.远程过程调用(RPC)是一种常用的分布式网络通信协议,他允许运行于一台计算机的程序调用 ...

  4. 每天收获一点点------Hadoop之初始MapReduce

    一.神马是高大上的MapReduce MapReduce是Google的一项重要技术,它首先是一个编程模型,用以进行大数据量的计算.对于大数据量的计算,通常采用的处理手法就是并行计算.但对许多开发者来 ...

  5. 每天收获一点点------Hadoop之HDFS基础入门

    一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...

  6. 每天收获一点点------Hadoop基本介绍与安装配置

    一.Hadoop的发展历史 说到Hadoop的起源,不得不说到一个传奇的IT公司—全球IT技术的引领者Google.Google(自称)为云计算概念的提出者,在自身多年的搜索引擎业务中构建了突破性的G ...

  7. Hadoop RPC机制

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.Hadoop底层的交互都是通过 rp ...

  8. 每天收获一点点------Hadoop概述

    一.Hadoop来历 Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明了倒排索引算法,通过加入了Map ...

  9. 每天收获一点点------Hadoop Eclipse插件的使用

    本文所用软件版本:myeclipe2014    hadoop1.2.1 1.安装Hadoop开发插件 下载hadoop-eclipse-plugin-1.2.1.jar,拷贝到myeclipse根目 ...

随机推荐

  1. cocos2d-x3.0 相对布局(一)

    2dx相对布局和Android非常类似.假设前完成Android它应该是easy入门. Size widgetSize = Director::getInstance()->getWinSize ...

  2. 0当执行游戏xc000007b错误的解决方法

    如图所示,这个错误是让很多玩家担心. 出现这个错误,可能是硬件的问题,也可能是软件的问题. 可是.因为硬件引起该问题的概率非常小,而且除了更换硬件之外没有更好的解决方法,因此本文将具体介绍怎样通过软件 ...

  3. 【iOS】彩虹渐变色 的 Swift 实现

    首先很感谢大家的支持与关注.<Web Color 的 Swfit 实现>一文一经公布.訪问量迅速攀升,让本人受宠若惊. 为表达感激之情,今天早上把彩虹渐变也顺手实现了. 最新代码& ...

  4. xp硬盘安装Fedora14 过程记录及心得体会(fedora14 live版本680M 和fedora14 DVD版本3.2G的选择)

    这次电脑奔溃了,奇怪的是直接ghost覆盖c盘竟然不中.之前电脑上硬盘安装的fedora14操作系统,也是双系统.不知道是不是这个问题,记得同学说过,在硬盘装fedora之后,要手动修改c盘隐藏的那个 ...

  5. Java Web整合开发(附录1) - 安装配置环境

    1. Install JDK http://blog.csdn.net/sonnet123/article/details/9169741 Download JDK http://www.oracle ...

  6. GDB十几分钟教程

    GDB十分钟教程 作者: liigo原文链接: http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx日期: 2006年1月16日 本文写给 ...

  7. DOM操作应用

    创建元素 document.createElement("li"); 添加节点 oUl.appendChild(oLi); 在某个元素之前插入一个节点 oUl.insertBefo ...

  8. 人人API 分享到人人功能 修改版

    最近在搞一个日程管理网站, 需要实现分享到人人功能, 所以找了一下人人API, 然后根据自己需要修改了一下. 首先得有一个人人给的js文件, 如下: var Renren = Renren || {} ...

  9. hdu 2899 hdu 3400 三分/几何

    hdu2899 : 水提,直接三分,事实上求导后二分也能够. #include<iostream> #include<cstdio> using namespace std; ...

  10. 大约apache 2.4.X虚拟主机配置问题的版本号后,

    重装系统,习惯性下载最新的wamp2.5,在各种配置,然后一切正常反应.数据库,代码. 然后打开浏览器,尼嘛,幸运的是,昨天,与虚拟域,其实403该. apache error log的信息是:AH0 ...