Hadoop源码分析笔记(三):Hadoop远程过程调用
来源:互联网 发布:ubuntu 移动硬盘 编辑:程序博客网 时间:2024/06/05 10:56
Hadoop远程过程调用
远程过程调用(RPC)
作为分布式系统,Hadoop中各个实体间存在着大量的交互,远程过程调用(Remote Procedure Call,RPC)让用户可以像调用本地方法一样调用另外一个应用程序提供的服务,而不必设计和开发相关的信息发送、处理和接收等具体代码,它提高了程序的互操作性。
简要来说,RPC就是允许程序调用位于其他机器上的过程(也可以是同一台机器的不同进程)。但机器A上的进程调用机器B上的进程时,A上的进程被挂起,而B上的被调用的进程开始执行。调用方使用参数将信息传送给被调用方。然后通过传回的结果得到信息。在这个过程中A是PRC客户,B是RPC服务器。同时,编程人员看不到任何消息的传递,这个过程对用户来说是透明的。其行为如同一个过程到另一个过程的调用一样。
RPC引入客户存根(Client Stub)和服务器骨架(Server Skeleton)来解决系统在有差异的情况下进行参数和结果的传递,并对通信双方的状态进行监控。
Java远程方法调用(RMI)
在某种程度上来看,RMI可以看成是RPC的Java升级版。和RPC一样,包含RMI的Java应用程序通常包括服务器程序和客户端程序。它提供了和PRC中类似的
标准的Stub/Skeleton机制。Stub代表可以被客户端引用的远程对象,位于客户端,并保持着远程对象的接口和方法列表。客户端应用调用远程对象时,Stub将调用请求,通过RMI的基础结构转发到远程对象上。接受到调用请求时,服务器端的Skeleton对象处理相关调用“远方”对象中的所有细节并调用Skeleton对象。
Java远程方法调用依赖于Java对象的序列化机制,他将调用的参数和返回值序列化并在网络中传递。
Hadoop远程过程调用
Hadoop远程过程调用实现使用Java动态代理和新输入/输出系统(NIO),Hadoop没有使用前面的Java RMI,而是实现了一套自己独有的节点间通信机制,理由和Hadoop使用Writable形式的序列化机制类似,有效的IPC(Inter-Process Communication,进程间通信)对于Hadoop来说是至关重要的,Hadoop需要精确控制进程间通信中比如连接、超时、缓存等通信细节,显然Java RMI达不到这些需求,Hadoop进程间通信机制,结合数据输出流(DataOutputStram)和数据输入流(DataInputStram)的Writable序列化机制,以及一个简洁的、低消耗的远程过程调用机制。
Java RMI的开发从远程接口的定义开始,远程接口必须继承java.rmi.Remote;在Hadoop远程过程调用中,也是通过一个IPC接口开始进行开发。Hadoop IPC接口必须继承自org.apche.hadoop.ipc.VersionedProtocol接口,代码如下:
public interface VersionedProtocol { /** * Return protocol version corresponding to protocol interface. * @param protocol The classname of the protocol interface * @param clientVersion The version of the protocol that the client speaks * @return the version that the server will speak */ public long getProtocolVersion(String protocol, long clientVersion) throws IOException;}
在Hadoop中,这个接口不是一个声明性接口,实现该接口对应的接口都必须实现这个方法。它有两个参数,分别是协议对应的接口名字和客户端期望的协议的版本号。方法则返回服务器端的接口实现的版本号。在建立IPC时,getProtocolVersion()方法用户检查通信的双方,保证他们使用了相同版本的接口。下面贴上一段利用Hadoop IPC接口实现自己的IPC应用。
//需要序列化的类public class IPCFileStatus implements Writable {private String filename; private long time; static { // register IPCFileStatus WritableFactories.setFactory ( IPCFileStatus.class, new WritableFactory() { public Writable newInstance() { return new IPCFileStatus(); } } ); } public IPCFileStatus() { } public IPCFileStatus(String filename) {this.filename=filename;this.time=(new Date()).getTime();}public String getFilename() {return filename;}public void setFilename(String filename) {this.filename = filename;}public long getTime() {return time;}public void setTime(long time) {this.time = time;}public String toString() {return "File: "+filename+" Create at "+(new Date(time)); }@Overridepublic void readFields(DataInput in) throws IOException { this.filename = Text.readString(in); this.time = in.readLong();}@Overridepublic void write(DataOutput out) throws IOException {Text.writeString(out, filename);out.writeLong(time);}}//接口public interface IPCQueryStatus extends VersionedProtocol {IPCFileStatus getFileStatus(String filename);}//实现类public class IPCQueryStatusImpl implements IPCQueryStatus {protected IPCQueryStatusImpl() {}@Overridepublic IPCFileStatus getFileStatus(String filename) {IPCFileStatus status=new IPCFileStatus(filename);System.out.println("Method getFileStatus Called, return: "+status);return status;}@Overridepublic long getProtocolVersion(String protocol, long clientVersion) throws IOException {System.out.println("protocol: "+protocol);System.out.println("clientVersion: "+clientVersion);return IPCQueryServer.IPC_VER;}}//服务器端public class IPCQueryServer {public static final int IPC_PORT = 32121;public static final long IPC_VER = 5473L;public static void main(String[] args) {try {ConsoleAppender append=new ConsoleAppender(new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN));append.setThreshold(Level.DEBUG);BasicConfigurator.configure(); IPCQueryStatusImpl queryService=new IPCQueryStatusImpl(); Server server = RPC.getServer(queryService, "0.0.0.0", IPC_PORT, 1, true, new Configuration());server.start();System.out.println("Server ready, press any key to stop");System.in.read();server.stop();System.out.println("Server stopped");} catch (Exception e) {e.printStackTrace();}}}//客户端public class IPCQueryClient {public static void main(String[] args) {try {System.out.println("Interface name: "+IPCQueryStatus.class.getName());System.out.println("Interface name: "+IPCQueryStatus.class.getMethod("getFileStatus", String.class).getName());InetSocketAddress addr=new InetSocketAddress("localhost", IPCQueryServer.IPC_PORT);IPCQueryStatus query=(IPCQueryStatus) RPC.getProxy(IPCQueryStatus.class, IPCQueryServer.IPC_VER, addr, new Configuration());IPCFileStatus status=query.getFileStatus("/tmp/testIPC");System.out.println(status);RPC.stopProxy(query);} catch (Exception e) {e.printStackTrace();}}}
Hadoop IPC的代码结构
Hadoop中与IPC相关的代码都在org.apache.hadoop.ipc包中,类简介如下:
RemoteExecption:远程异常,应用于IPC客户端,表示远程过程调用中的错误。
Status:枚举类,定义了远程过程调用的返回结果,包括SUCCESS、ERROR、FATAL等情况。
VersionedProtocol接口:前面已经介绍过,Hadoop IPC的远程接口都扩展自VersionedProtocol.
ConnectionHeader:IPC客户端与服务器端建立连接时发送的消息头。
Client:包含了与IPC客户端相关的代码。它的内部类包括:Client.Connection、Client.ConnectionId和Client.Call、Client、ParallelCall等类
Server:包含了与IPC服务端相关的代码。它的内部类包括:Server.Connection与Server.Call。【Listener、Handler、Responder】这三个类是对远程调用的处理它们都继承自java.lang.Thread类,在各自的线程中运行。
RPC类:它在Client和Server类的基础上面实现了Hadoop IPC的功能。
版权申明:本文部分摘自【蔡斌、陈湘萍】所著【Hadoop技术内幕 深入解析Hadoop Common和HDFS架构设计与实现原理】一书,仅作为学习笔记,用于技术交流,其商业版权由原作者保留,推荐大家购买图书研究,转载请保留原作者,谢谢!
- Hadoop源码分析笔记(三):Hadoop远程过程调用
- Hadoop源码分析笔记(七):HDFS非远程调用接口
- hadoop实现原理 (三) 远程过程调用
- Hadoop远程过程调用
- hadoop 2.7.3 源码分析(三):hadoop远程调试
- Hadoop RPC远程过程调用源码解析及实例
- Hadoop最新版 RPC远程过程调用源码解析及实例
- Hadoop RPC远程过程调用源码解析及实例
- Hadoop RPC远程过程调用源码解析及实例
- Hadoop源码分析笔记(十四):名字节点--远程接口ClientProtocol
- Hadoop源码分析(三)--------------job提交过程分析(3)之job的split过程
- Hadoop中Mapper过程的源码分析
- Hadoop读写过程的源码分析
- hadoop源码远程debug
- Hadoop HDFS源码学习笔记(三)
- Hadoop源码分析笔记(一):Hadoop Configuration详解
- Hadoop源码分析笔记(二):Hadoop序列化与压缩
- Hadoop源码分析笔记(四):Hadoop文件系统简介
- 一些关于STM32 分析的文章
- MongoDB学习笔记《二》
- ubuntu空间扩容问题
- android 把bitmap转成drawble后宽高不一致的解决方法
- STM32之如何封装自己的lib库
- Hadoop源码分析笔记(三):Hadoop远程过程调用
- oracle dba 面试题集锦1
- JavaScript中的集合及效率
- 使用自定义标签来控制标签体是否执行
- shell中的通配符以及特殊符
- PLSQL连接64位ORACLE
- 《opencv基础教程》
- python中文编码问题
- 关于对DSP28系列计算FFT的时间的探讨