推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html
全部博文(594)
分类: HADOOP
2015-09-07 12:47:15
2.4.1.2. Client.ConnectionId 8
2.4.1.4. Client.ParallelResults 8
本文主要是介绍Hadoop RPC子系统的关键模块的结构和流程。
HadoopRPC逻辑上分成三部分,如上图所示。
RPC对外接口。
RPC服务端的实现。
RPC客户端的实现。
RPC是对外的接口类,主要提供两个方法:getProxy和getServer。
? 说明
RPC服务端接口。为指定协议的实例,在指定的地址和端口上启动服务。
? 函数原型
public static Server getServer(
final Object instance,
final String bindAddress,
final int port,
final int numHandlers,
final boolean verbose,
Configuration conf) throws IOException;
? 参数说明
1) Instance
RPC Server端对象实例,也就是RPC Client调用的接口实例。
2) bindAddress
RPC Server监听的IP地址。
3) Port
RPC Server监听的端口号。
4) numHandlers
处理Call队列的Handler线程个数。
5) Verbose
6) conf
配置项。
? 说明
RPC客户端接口,创建一个指定服务端的代理。
? 函数原型
public static VersionedProtocol getProxy(
Class<? extends VersionedProtocol> protocol,
long clientVersion,
InetSocketAddress addr,
UserGroupInformation ticket,
Configuration conf,
SocketFactory factory) throws IOException;
? 参数说明
1) protocol
RPC Server提供RPC服务的接口。
2) clientVersion
客户端的版本号。
3) addr
RPC Server地址。
4) ticket
5) conf
配置项。
6) factory
SOCKET工厂。
抽象的RPC服务,提供Call队列。
Server的实现。
RPC服务端的监听者,用来接受RPC客户端的连接请求和数据的收发。
RPC服务端的Call处理者,和Server.Listener通过Call队列交互。
RPC服务端的响应者。Server.Handler向RPC客户端发送响应是异步非阻塞的,如果有未发送出的数据,交由Server.Responder来完成。
提供接收数据,解析数据包的功能。
持有客户端的Call信息。
接收RPC Client的调用,并编码成Call对象,放入到Call队列中,这个过程在Listener线程中完成。
? 步骤说明:
1) Listener线程循环等待RPC客户端的发送数据过来
2) 当有数据可以接收时,调用Connection的readAndProcess方法
3) Connection边接收边对数据进行处理,如果接收到一个完整的Call包,则构建一个Call对象,并将这个Call对象PUSH到Call队列中,由Handler线程来处理Call队列中的所有Call。
处理Call队列中的每个请求,在Handler线程中完成。
? 步骤说明:
1) Handler线程循环监听Call队列,如果Call队列为空,则进入wait状态,否则按FIFO规则从Call队列取出Call
2) 将Call交给RPC.Server处理(调用RPC.Server的Call)
3) 借助JDK提供的Method,完成对目标方法的调用
4) 返回响应。由于响应需要通过SOCKET返回给RPC客户端,所以响应的类型必须是Writable。
RPC客户端的实现和入口类。
到RPC服务端对象连接的标识。
存储Call调用信息。
存储响应。
对InvocationHandler的实现,提供invoke方法,截获RPC客户端对RPC服务端对象的调用。
用来序列化和反序列化RPC客户端的调用信息,包括方法名和参数信息。
客户端RPC调用的处理流程,转化为SOCKET通信。
? 步骤说明:
1) RPC客户端发起一个RPC调用时,JAVA的反射机制会截获该调用,并转化为对Client.call的调用
2) 调用getConnection建立到RPC服务端的连接
3) 通过Connection将序列化后的参数发送到RPC服务端
4) 等待RPC服务端返回响应。
该流程用来建立到RPC Server端的连接,到一个RPC Server端只会建立一个连接。
? 步骤说明:
1) 根据RPC服务端的地址和接口从连接池中获取一个,如果取到Connection则直接返回
2) 否则新建一个Connection,并将它放入到连接池中
3) 然后通过SocketFactory创建一个Socket,并建立到RPC服务端的连接,如果连接不成功,则重试
4) 创建和关联输入和输出流对象。
客户端发起的RPC调用都是同步的,而服务端处理RPC调用是异步的。客户端调用线程以阻塞同步的方式发起RPC连接,及RPC调用,将参数等信息发送给Listener,然后就等待Connection接收完响应返回。
Listener负责接收RPC连接,和RPC数据,当一个Call的数据接收完后,组装成Call,并将Call放入由Handler提供的Call队列中。
Handler线程一直监听Call队列,如果Call队列不为空,则按队列方式取出一个Call,并转为实际调用,以非阻塞方式将响应发回给Connection,剩下未发送完毕的响应交给Responder处理。