RPC(Remote Procedure Call)————远程过程调用协议

 

Hadoop RPC在Hadoop中应用非常广泛,Client、DataNode、NameNode之间的通讯全依赖于它

 

(1)它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网络通信细节。对我们来说是透明的。因此,它经常用于分布式网络通信中。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。使得开发包括网络分布式多程序在内的应用程序更加容易。

 

(2)Hadoop的进程间交互都是通过RPC来进行的,比如Namenode与Datanode之间,Jobtracker与Tasktracker之间等。因此,可以说Hadoop的运行就是建立在RPC基础之上的。

 

RPC的显著特点

 

  • 透明性:远程调用其他机器上的程序,对用户来说就像是调用本地方法一样;
  • 高性能:RPC Server能够并发处理多个来自Client的请求;
  • 可控性:jdk中已经提供了一个RPC框架—RMI,但是该PRC框架过于重量级并且可控之处比较少
  • 所以Hadoop RPC实现了自定义的PRC框架。

 

一个典型的RPC框架主要包括以下模块

 

  • 通信模块:两个相互协作的通信模块实现请求—–应答协议。
  • 代理程序:客户端和服务器端均包含代理程序。
  • 调度程序:调度程序接受来自通信模块的请求消息,并根据其中的标志选择一个代理程序处理。

 

RPC框架分层

 

  • 序列化层:Clent与Server端通信传递的信息采用了Hadoop里提供的序列化类或自定义的Writable类型;
  • 函数调用层:Hadoop RPC通过动态代理以及java反射实现函数调用;
  • 网络传输层:Hadoop RPC采用了基于TCP/IP的socket机制;
  • 服务器端框架层:RPC Server利用java NIO及采用事件驱动的I/O模型,提高RPC Server的并发处理能力;???????????????

    

客户端和服务器端的关系

 

  • Client-NameNode之间,其中NameNode是服务器
  • Client-DataNode之间,其中DataNode是服务器
  • DataNode-NameNode之间,其中NameNode是服务器
  • DataNode-DateNode之间,其中某一个DateNode是服务器,另一个是客户端

 

Hadoop RPC主要对外提供两种接口

 

  • public static VersionedProtocol getProxy/waitForProxy()
  • 构造一个客户端代理对象(该对象实现了某种协议),用于向服务器端发送RPC请求;
  • public static Server getServer()
  • 为某个协议(实际上是Java接口)实例构造一个服务器对象,用于处理客户端发送的请求;

 

 

例如:操作Hadoop时使用FileSystem类,它的内部有个DFSClient对象,这个对象负责与NameNode打交道。

在运行时,DFSClient在本地创建一个NameNode的代理,然后操作这个代理通过网络远程调用到NameNode的方法,也能返回值。

 

 

hadoop tcp hadoop tcp udp_hadoop tcp

 

RPC实体

 

Listener

监听RPC Server的端口,如果客户端有连接请求到达,它就接受连接。

然后把连接转发到某个Reader,让Reader去读取那个连接的数据。

如果有多个Reader的话,当有新连接过来时,就在这些Reader间顺序分发。

 

Reader

从某个客户端连接中读取数据流,把它转化成调用对象(Call),然后放到调用队列(call queue)里

 

Handler

真正做事的实体。它从调用队列中获取调用信息,然后反射调用真正的对象,得到结果,然后再把此次调用放到响应队列(response queue)里

 

Responder

它不断地检查响应队列中是否有调用信息,如果有的话,就把调用的结果返回给客户端。

 

hadoop tcp hadoop tcp udp_Hadoop_02

 

RPC实现流程

 

RPC采用客户机/服务器模式

 

通信模块:实现请求应该协议。主要分为同步方式和异步方式。

stub程序:客户端和服务器均包含stub程序(代理程序)。使得远程函数表现的跟本地调用一样,对用户程序完全透明。

调度程序:接受来自通信模块的请求消息,根据标识选择stub程序处理。并发量大一般采用线程池处理。

客户程序/服务过程:请求发出者和请求的处理者

 

一个RPC请求从发送到获取处理结果,所经历的步骤如下:

 

  • 客户程序以本地方式调用系统产生的Stub程序;
  • 该Stub程序将函数调用信息按照网络通信模块的要求封装成消息包,并交给通信模块发送到远程服务器端;
  • 远程服务器端接收到此消息后,将此消息发送给相应的Stub程序;
  • Stub程序拆封消息,形成被调过程要求的形式,并调用对应的函数;
  • 被调用函数按照所获参数执行,并将结果返回给Stub程序;
  • Stub将此结果封装成消息,通过网络通信模块逐级地传送给客户程序;

hadoop tcp hadoop tcp udp_Server_03

 

 

RPC Client主要流程

 

  • RPC Client发起RPC Call,通过JAVA反射机制转化为对Client.call调用
  • 调用getConnection得到与RPC Server的链接,每一个Client都维护一个HashMap结构的到Server的连接池
  • 通过Connection将序列化后的参数发送到RPC服务端
  • 阻塞方式等待RPC服务端返回响应

 

 

RPC Server的主要流程

 

RPC Server作为服务的提供者主要有两部分组成:接收Call调用和处理Call调用。

接收Call调用负责接收来自RPC Client的调用请求,编码成Call对象放入到Call队列中。这一过程有Server.Listener完成,具体步骤如下:

 

  • Listener线程监听RPC Client发过来的数据
  • 当有数据可以接收时,调用Connection的readAndProcess方法
  • Connection边接受数据边处理数据,当接到一个完整的Call包,则构建一个Call对象。PUSH到Call队列中,有Handler来处理Call队列中的所有Call,处理完的Call调用负责处理Call队列中的每一个调用请求,由Handler线程来完成。
  • Handler线程监听Call队列,如果Call队列非空,按FIFO规则从Call队列中取出Call
  • 将Call交给RPC.Server来处理
  • 借助JDK提供的Method,完成对目标方法的调用,目标方法由具体的业务逻辑实现
  • 返回响应。Server.Handler按照异步非阻塞的方式向RPC Client发送响应,如果有未发送出的数据,则交由Server.Responder来完成。
  •  

hadoop tcp hadoop tcp udp_hadoop tcp_04