13. Hadoop RPC框架之通信模块

Hadoop作为分布式存储系统,各个节点之间的通信和交互是必不可少的,所以需要实现一套节点间的通信交互机制,Hadoop框架并没有使用JDK自带的RMI(Remote Method Invocation,远程方法调用),而是基于IPC(Inter-Process Communications,进程间通信)模型实现了一套高效的轻量级RPC框架,这套RPC框架底层采用了JavaNIO、Java动态代理以及protobuf等基础技术。

Hadoop RPC框架与其他RPC框架一样,实现了上篇文章描述到的结构,下来来看看各个模块在Hadoop RPC中的实现

通信模块

Hadoop 实现了org.apache.hadoop.ipc.Client(简称Client类)以及org.apache.hadoop.ipc.Server(简称Server类)提供的基于TCP/IP Socket的网络通信功能,客户端可以通过Client类将序列化的请求发送到远程服务器,服务器会通过Server类接收来自客户端的请求

客户端在发送请求到远程服务器前需要先将请求序列化,然后调用Client.call()方法发送这个请求到远程服务器。为了使RPC机制更加健壮,Hadoop RPC允许客户端配置使用不同的序列化框架序列化RPC请求(例如protobuf、avro),这就要求Client.call()方法的定义更加通用,也就是Client.call()方法可以发送任意序列化框架产生的RPC请求,所以Client.call()方法定义如下

public Writable call(RPC.RpcKind rpcKind, Writable rpcRequest,
    ConnectionId remoteId, int serviceClass,
    AtomicBoolean fallbackToSimpleAuth) throws IOException {
  // 具体代码省略
}

rpcKind参数用于描述RPC请求的序列化工具的类型,rpcRequest参数用于记录序列化后的RPC请求。注意,rpcRequest是Writable类型的(Hadoop框架自己定义的序列化类型),这就要求客户端Stub程序将RPC请求序列化后保障成Writable类型,所以WritableRpcEngine定义了Invocation类包装Writable序列化的RPC请求,而ProtobufRpcEngine则定义了RpcRequestWrapper包装protobuf序列化的RPC请求。

在看服务端,为了提高性能,Server类采用了Java NIO提供的基于Reactor设计模式的事件驱动I/O模型,当Server完整地从网络接收一个RPC请求后,会调用call()方法响应这个请求,该方法定义如下

public abstract Writable call(RPC.RpcKind rpcKind, String protocol,
    Writable param, long receiveTime) throws Exception;

Server.call()方法的定义与Client.call()方法很相似

你可能感兴趣的:(13. Hadoop RPC框架之通信模块)