版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Oracle·WDPe·WDP分布式文件系统(RPC原理)Oracle高校大数据课程系列本课目标理解RPC的原理掌握JAVA远程方法调用掌握动态代理技术掌握HadoopRPC原理与应用Coursecatalogue课程目录RPC原理1Java远程方法调用2Java动态代理3Hadoop中的RPC4RPC概述很多分布式系统,如浏览器和服务器间的通信,需要在不同的实体中显式交换消息,处理诸如消息的编解码、消息的发送和接收等非常具体的任务。如何隐藏底层通信的细节是实现分布式系统访问透明性的重要议题之一。远程过程调用(RemoteProcedureCall,RPC)由Birrell和Nelson于1984年引入到分布式计算领域,是解决上述访问透明性的一套精妙方案。随着RPC的发展,出现了大量的相关技术,如XML-RPC、JSON-RPC(JavaScriptObjectNotationRPC),CORBA(CommonObjectRequestBrokerArchitecture,公共对象请求代理体系结构)和RMI(RemoteMethodInvocation,远程方法调用)等。本节讨论的HadoopIPC(Inter-ProcessCommunication,进程间通信)属于RPC的一种比较简单的实现。RPC原理
传统的过程调用中,
主程序将参数压入栈内并调用过程,
这时候主程序停止执行并开始执行相应的过程。
被调用的过程从栈中获取参数,
然后执行过程函数:执行完毕后,
将返回参数入栈〈或者保存在寄存器里〉,
并将控制权交还给调用方。
调用方获取返回参数,
并继续执行。传统过程调用RPC原理RPC跨越了不同的进程(theClient和theServer),其调用示例如下所示。当theClient需要调用一个远程过程的时候,通过theClient将参数打包成为一个消息,并附加被调用过程的名字(指明要调用服务器上的哪一个过程〉,然后发送消息到服务器。theClient发送完消息以后,必须等待服务器的应答,这个时候,执行流是空闲的。RPC的Server运行时会阻塞在接收消息的调用上,当接到客户端的请求后,它会解包以获取请求参数,这类似传统过程调用中,被调用函数从栈中接收参数,然后确定调用过程的名字并调用相应过程。调用结束后,返回值通过主程序打包并发送回客户端,通知客户端调用结束。RPC进程调用RPC原理实现RPC需要关注下面三个问题:口RPC的语法应该与高级程序设计语言中的本地过程调用的语法有相同的外观;口RPC和本地调用的语义尽可能地类似,如参数传递中包含的语义;口RPC的接收者〈也就是服务器上业务代码的执行〉应该如同一个传统的调用;RPC原理RPC引人客户存根(ClientStub)和服务器骨架(ServerSkeleton)解决了前面提及的问题,可以发现,如果调用方法的接口确定,那么图中RPC调用过程的很多步骤都可以自动生成,生成的这些步骤正是客户存根和服务器骨架的重要组成部分。RPC的实现一般形式RPC原理-架构图RPC架构图Coursecatalogue课程目录RPC原理1Java远程方法调用2Java动态代理3Hadoop中的RPC4Java远程方法调用—服务器端从JavaRMI的开发往往从远程接口的定义开始,本例使用的远程接口如下:RMIQueryStatus接口中的getFileStatus()方法接受一个字符串参数filename,返回一个RMIQueryStatus对象,这个方法简单地模拟了文件系统中对文件元信息的查询功能。1. importjava.rmi.Remote;2. importjava.rmi.RemoteException;3. //远程接口必须声明为public4. //远程接口必须继承自java.rmi.Remote5. publicinterfaceRMIQueryStatusextendsRemote{6. //远程接口中的函数必须将java.rmi.RemoteException声明于其throws子句内7. RMIFileStatusgetFileStatus(Stringfilename)8. throwsRemoteException;9. }Java远程方法调用—服务器端RMIQueryStatusImpl继承自UnicastRemoteObject,并实现了RMIQueryStatus接口。1. publicclassRMIQueryStatusImpl2. extendsUnicastRemoteObjectimplementsRMIQueryStatus{3. ……4. @Override5. publicRMIFileStatusgetFIleStatus(Stringfilename)throws……{6. RMIFileStatusstatus=newRMIFileStatus(filename);7. ……8. returnstatus;9. }10. }Java远程方法调用—服务器端启动服务器FMIQueryStatusServer,该服务器的main方法创建RMIQueryStatusImpl对象,并与刚才启动的对象注册点对话,将远端对象绑定到名字“rmi://:12090/query”上(应用这个例子的时候,请将这个URI的主机部分改为相应的主机名)。虽然main()方法的执行很快就结束了,但服务器还会继续运行,不过,用户需要写的服务器代码就只有这么多。1. publicstaticvoidmain(String[]args){2. try{3. //创建RMIQueryStatusImpl对象4. RMIQueryStatusImplqueryService=newRMIQueryStatusImpl();5. LocateRegistry.createRegistry(12090);6. //绑定远端对象到名字7. Naming.rebind(RMI_URL,queryService);8. System.out.println(“Serverready”);9. }catch(Exceptione){10. e.printlnStackTrace();11. }12. }Java远程方法调用—客户端
客户端对象在调用远程方法之前,则需要被调用方法所属对象的一个远程引用。客户端RMIQueryStatusClient从远端对象注册点中,通过Naming.lookup()获取远程引用。一旦获取对象引用,并恢复了对象类型,客户端就可以使用此引用,调用远程对象的远程方法,即getFileStatus()方法。1. try{2. //创建RMIQueryStatusImpl对象3. RMIQueryStatusquery=4. (RMIQueryStatus)Naming.lookup(RMIQueryStatusServer.RMI_URL);5. //调用远程方法;该调用如同调用本地方法6. RMIQueryStatusstatus=query.getFileStatus(“/tmp/testRMI”);7. System.out.println(status);8. }catch(RemoteExceptione){9. //远程方法和普通方法的一个差别:远程方法可能抛出RemoteException异常10. e.printStackTrace();11. }Coursecatalogue课程目录RPC原理1Java远程方法调用2Java动态代理3Hadoop中的RPC4Java动态代理
代理对象往往实现和目标对象一致的接口,并作为目标对象的代替,接收对象用户(Client)的调用,并将全部或部分调用转发给目标对象,如下图所示。在这个过程中,实现代理接口和调用转发,是代理对象必须完成的两个重要任务,缺一不可。
Java动态代理架构Java动态代理通过Method对象的invoke()方法,在目标对象target上使用相同的参数args,调用了同一个方法(它们都实现了同一个接口),并将结果返回给调用者。Java动态代理详细过程Coursecatalogue课程目录RPC原理1Java远程方法调用2Java动态代理3Hadoop中的RPC4Hadoop中RPCRPC实际上是分布式计算中C/S(Client/Server)模型的一个应用实例,对于HadoopRPC而言,它具有以下几个特点。❑透明性。这是所有RPC框架最根本的特点,即当用户在一台计算机的程序调用另外一台计算机上的子程序时,用户自身不应感觉到其间涉及跨机器间的通信,而是感觉像是在执行一个本地调用。❑高性能。Hadoop各个系统(如HDFS、YARN、MapReduce等)均采用了Master/Slave结构,其中,Master实际上是一个RPCServer,它负责处理集群中所有Slave发送的服务请求,为了保证Master的并发处理能力,RPCServer应是一个高性能服务器,能 够高效地处理来自多个Client的并发RPC请求。❑可控性。JDK中已经自带了一个RPC框架—RMI(RemoteMethodInvocation,远程方法调用),之所以不直接使用该框架,主要是考虑到RPC是Hadoop最底层最核心的模块之一,保证其轻量级、高性能和可控性显得尤为重要,而RMI重量级过大且用户可控之处太少(如网络连接、超时和缓冲等均难以定制或者修改)。Hadoop中RPC--总体架构Hadoop中RPC—使用方法
定义一个ClientProtocol通信接口,声明了echo()和add()两个方法。需要注意的是,Hadoop中所有自定义RPC接口都需要继承VersionedProtocol接口,它描述了协议的版本信息。interfaceClientProtocolextendsorg.apache.hadoop.ipc.VersionedProtocol{//版本号,默认情况下,不同版本号的RPCClient和Server之间不能相互通信publicstaticfinallongversionID=1L;Stringecho(Stringvalue)throwsIOException;intadd(intv1,intv2)throwsIOException;}Hadoop中RPC—使用方法
HadoopRPC协议通常是一个Java接口,用户需要实现该接口。对ClientProtocol接口进行简单的实现如下所示publicstaticclassClientProtocolImplimplementsClientProtocol{//重载的方法,用于获取自定义的协议版本号,publiclonggetProtocolVersion(Stringprotocol,longclientVersion){returnClientProtocol.versionID;}//重载的方法,用于获取协议签名publicProtocolSignaturegetProtocolSignature(Stringprotocol,longclientVersion,inthashcode){returnnewProtocolSignature(ClientProtocol.versionID,null);}publicStringecho(Stringvalue)throwsIOException{returnvalue;}publicintadd(intv1,intv2)throwsIOException{returnv1+v2;}}Hadoop中RPC—使用方法构造并启动RPCServer,直接使用静态类Builder构造一个RPCServer,并调用函数start()启动该ServerServerserver=newRPC.Builder(conf).setProtocol(ClientProtocol.class).setInstance(newClientProtocolImpl()).setBindAddress(ADDRESS).setPort(0).setNumHandlers(5).build();server.start();Hadoop中RPC—使用方法构造RPCClient并发送RPC请求,使用静态方法getProxy构造客户端代理对象,直接通过代理对象调用远程端的方法。经过以上四步,我们便利用HadoopRPC搭建了一个非常高效的客户机–服务器网络模型。proxy=(ClientProtocol)RPC.getProxy(ClientProtocol.class, ClientProtocol.versionID,addr,conf);intresult=proxy.add(5,6);StringechoResult=proxy.echo("result");Hadoop中RPC—类分析(客户端)Hadoop中RPC—类分析(服务器端)RPC架构图Coursecatalogue课程目录RPC原理1Java远程方法调用2Java动态代理3Hadoop中的RPC4ProtocolBufferProtocolBuffers是在Google内部广泛使用的序列化与RPC框架,是几乎所有Google服务的黏合剂,2008年Google将ProtocolBuffers开源.。一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化/反序列化。它很适合做数据存储或RPC的数据交换格式,常用作通信协议、数据存储等领域的与语目无关、平台无关、可扩展的序列化结构数据格式。ProtocolBuffers官方网站这样描述它的优点:□平台无关、语言无关;□高性能,解析速度是XML的20~100倍;□体积小,文件大小仅是XML的1/2~1/3;□使用简单;□兼容性好。ProtocolBuffer通常编写一个ProtocolBuffers应用需要以下三步:1)定义消息格式文件,通常以proto作为扩展名;2)使用Google提供的ProtocolBuffers编译器生成特定语言(目前支持C++、Java、Python三类语言)的代码文件;3)使用ProtocolBuffers库提供的API来编写应用程序。ProtocolBuffer步骤1定义消息格式文件person.proto,该文件描述了通讯录中某个人的基本信息,内容如下:packagetutorial; //自定义的命名空间optionjava一package="com.example.tutorial"; //生成文件的包名messagePerson{requiredstringname=1;//待描述的结构化数据requiredint32id=2;//required表示这个字段不能为空optionalstringemail=3;//数字“2”表示字段的数字别名 //optional表示该字段可以为空messagePhoneNumber{ //内部messagerequiredstringnumber=1;optionalint32type=2;repeatedPhoneNumberphone=4;ProtocolBuffer步骤2使用Google提供的ProtocolBuffers编译器生成Java语言,命令如下:protoc-java_out=.to注意,上面的命令运行时的当前路径是to所在目录。步骤3使用ProtocolBuffers库提供的API编写应用程序。该例子创建了一个Person对象,先将该对象保存到文件example.txt中,之后又从文件中读出并打印出来。publicclassProtocolBufferExample{staticpublicvoidmain(String[]argv){Personpersonl=Person.newBuilder().setName("DongXicheng").setEmail("").setld(lllll).addPhone(Person.PhoneNumber.newBuilder().setNumber().setType(0)).addPhone(Person.PhoneNumber.newBuilder().setNumber("01025689654").setType(1)).build();try{FileOutputStreamoutput=newFileOutputStream("example.txt");personl.writeTo(output);output.close();}catch(Exceptione){System.out.printIn("WriteError!");FilelnputStreaminput=newFilelnputStream("example.txt");Personperson2=Person.parseFrom(input);System.out.println("person2:"+person2);}catch(Exceptione){System.out.println("ReadError!");ApacheAvroApacheAvro是Hadoop下的一个子项目。它本身既是一个序列化框架,同时也实现了RPC的功能。Avro官网描述Avro的特性和功能如下:□丰富的数据结构类型;□快速可压缩的二进制数据形式;□存储持久数据的文件容器;□提供远程过程调用RPC;□简单的动态语言结合功能。ApacheAvro编写一个Awo应用也需如下三步:1)定义消息格式文件,通常以avro作为扩展名;2)使用Avro编译器生成特定语言的代码文件(可选);3)使用Avro库提供的API来编写应用程序。ApacheAvro步骤1定义消息格式文件person.avro,该文件描述了通讯录中某个人的基本信息,内容如下:{"namespace":"com.example.tutorial","type":"record",’’name":"Person","fields":[{"name”:"name","type":"string"},{"name":"id","type":"int”},{"name":"email”,"type":[’’string","null"]},{"name":"phone","type":{"type":"array","items":{"type":"record","name":"PhoneNumber","fields":[{"name":"number","type":"string"},{"name":’’type","type": ["int","null"]}}}}}}}ApacheAvro步骤2使用Avro编译器生成Java语言,命令如下: java-jaravro-tools-1.7.4.jarcompileschemaperson.avro.注意,上面的命令运行时的当前路径是person.avro所在目录。步骤3使用Avro库提供的API来编写应用程序。该例子创建一个Person对象,先将该对象保存到文件example.txt中,之后从文件中读出并打印。publicclassAvroExample{staticpublicvoidmain(String[]argv){PhoneNumberphoneNumberl=PhoneNumber.newBuilder().setNumber().setType(0).build();PhoneNumberphoneNumber2=PhoneNumber.newBuilder().setNumber("01025689654").setType(1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 四川省泸州市龙马潭区五校联考2024-2025学年七年级上学期期中地理试题(含答案)
- 房产买卖合同补充协议模板 保障双方权益
- 陕西房屋拆迁产权调换协议书
- 全面个人汽车租赁合同协议指南
- 家庭财务规划协议书
- 医疗器械产品售后服务协议书2024年
- 委托放款合同撰写指南
- 2024年电子商务运营合作完整协议书范文
- 课程设计生产化妆品
- 典型合作合同格式
- 厦门宏发继电器基础知识(课堂PPT)
- 储罐大修施工方案
- 专业安全检查表-吊索吊具
- 国槐在园林绿化中的作用
- 2022年住宅室内装饰装修管理办法全文
- 经纬度数转换工具
- 监理质量管理体系
- 消弧线圈基础施工方案
- MES运行管理办法
- 小学一年级数学小学一年级数学新思维训练(课堂PPT)
- 地层编号原则
评论
0/150
提交评论