RPC是Hadoop的基础组件,提供分布式环境下的对象调用功能。之前用了三天时间分析与测试RPC,目的是想弄清楚它的整个运行机制。
概括的说,RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
前言:
我们一般情况下通过客户端调用服务,都是现在同一个JVM中,通过在本地JVM中创建一个服务对象,进而通过调用该对象调用其内部的相关服务方法。
当客户端与服务不在同一个JVM中,一般情况下服务被单独放在一台服务器上运行,然后将服务发布为一个webservice,此时客户端通过UDDI找到WSDL描述文档后,可以通过SOAP调用你建立的Web服务中的一个或多个操作。但SOAP协议冗余较多,占用网络带宽大,并不适合分布式机器之间频繁的通信操作。
RPC,专业名称为远程过程调用。RPC协议比SOAP更加精简,通过RPC我们可以从网络上的计算机请求服务,而不需要了解底层网络协议。Hadoop底层的交互都是通过RPC进行的。例如Client、DataNode、NameNode之间的通讯全靠它。我们操作HDFS的时候,使用的是FileSystem类,它的内部有个DFSClient对象,这个对象负责与NameNode打交道。在运行时,DFSClient在本地创建一个NameNode的代理,然后就操作这个代理,这个代理就会通过网络,远程调用到NameNode的方法,返回相应的值。
RPC模式
在java的网络编程中:当客户端发送一个字节给服务端时,服务端必须也要有一个读字节的方法在阻塞等待;反之亦然。这种我把它称为底层的通信协议。于是我们就可以想像一下,如果不使用RPC,那么在分布式调用中流程应该是样:服务器端先创建ServerSocket,在指定的ip地址和端口上监听,客户端创建到远程连接的Socket,待socket套接字完毕,我们可以从套接字拿到输入输出流InputStream,OutputStream。接着客户端就可以往输出流写序列化的参数,服务器端将读到的输入流中参数流进行反序列化成程序支持的类型,然后将处理的结果再序列化到输出流,发送给客户端。RPC就是基于此,将Socket程序进行了封装,并且定义了许多接口,将接口和接口中的方法称为协议,客户端和服务端只要实现这些接口中的方法就可以进行通信了。
工作原理
运行时,一次客户端对服务端的RPC调用,其内部操作大致有如下十步:
当然,这只是RPC实现的一个非常基础性的简单原理,便于理解。真实的RPC框架也是基于此原理,只不过在此基础上增加了许多优化和容错的功能!
基于以上工作原理,我在Github上上传了一个利用Hadoop RPC框架进行服务调用的小程序,结合起来可以更深刻的理解它的原理和应用。
下载地址:https://github.com/Jerry-Fu/HadoopRpcApplication/