HDFS源码分析(1)--RPC解析

首先需要声明的是,我是基于Hadoop 3.0的源码

什么是RPC

    RPC:远程过程调用,怎么理解这个概念呢,就是说比如有两台服务器A、B,A服务器上的程序想要调用B服务器上的某个方法就像在本地调用一样,能够的到结果或者失败之后的异常。那么这个过程中涉及到几个部分呢。这里先举一个简单的例子来说明一下。

    RPC可以简单的抽象成一个打电话的例子(虽然有所不同,但是初期这样可以有助于理解)。如果我们在公司因为下雨然后想关上家里的窗户,我们可能伸手去关掉吗?如果你不是在家办公显然不可能。但是你可以打电话叫你的家人或者房东帮你关上,并且叫他关上之后给你一个答复,所以你通过这个过程关上了窗户,这就是RPC,你通过远程调用了房东或者家人的手去把窗户关上了。那接下来看看这个过程需要解决的几个问题。

1、  通信问题:如果没有电话,那么上面这个过程肯定不可能实现,你也许说我公司离家近,我可以靠喊,但是喊也是一种通信,我们需要一种通信手段去和远程的服务器建立联系。在Hadoop中使用的是socket通信。

2、  序列化问题:我们在通电话的过程还需要将我们说的话转化成电磁波传送到房东的手机上在转化成声音,这就是一个序列化和反序列化的过程。在程序中我们也需要将调用的方法参数等等信息进行序列化,然后传输到远程服务器上,再反序列化成相应的对象参数。

 

我们暂时就这样去理解RPC,当然RPC不止这样。更深层的东西后续会讲解,我们先来说一下HDFS中如何解决上面这两个问题的。

一、序列化问题

Writable接口:Hadoop中用于序列化对象的接口,包含在org.apache.hadoop.io包中。Writable接口中只定义了两个方法

HDFS源码分析(1)--RPC解析

write(DataOutput out)方法用于将对象写入到数据流中。

readFields(DataInput in)方法用于从数据流中读取对象。

这是源码中自带的一个自定义Writable对象的代码,在Hadoop中要序列化一个对象只需实现Writable接口即可。

public class MyWritable implements Writable {
*       // Some data
*       private int counter;
*       private long timestamp;
*
*       // Default constructor to allow (de)serialization
*       MyWritable() { }
*
*       public void write(DataOutput out) throws IOException {
*         out.writeInt(counter);
*         out.writeLong(timestamp);
*       }
*
*       public void readFields(DataInput in) throws IOException {
*         counter = in.readInt();
*         timestamp = in.readLong();
*       }
*
*       public static MyWritable read(DataInput in) throws IOException {
*         MyWritable w = new MyWritable();
*         w.readFields(in);
*         return w;
*       }
*     }

RPC中的序列化。在RPC中的对象序列化有一个专门的类RPCWritable,这是一个抽象类,它实现了Writable接口。

注意:在RPCWritable类中,它废除了Writable接口中的两个方法,另外定义了两个抽象方法去实现序列化和反序列化操作。

HDFS源码分析(1)--RPC解析

新的方法为:

// methods optimized for reduced intermediate byte[] allocations.
abstract void writeTo(ResponseBuffer out) throws IOException;
abstract <T> T readFrom(ByteBuffer bb) throws IOException;

RPCWritable的子类有:WritableWrapper,ProtobufWrapper,Buffer

这三个子类分别用于包装Writable、protobuf、和从字节缓冲器解码Writable和Protobuf。

在Hadoop3.0中,官方默认使用谷歌的Protobuf作为序列化框架,有关Protobuf的知识我将在后续中单独介绍一下。


二、通信问题

Hadoop中PRC的通信问题使用的IPC通信框架,使用基于NIO的Socket编程实现。传统的socket通信模型包括客户端和服务端。在RPC通信中也不例外。在org.apache.hadoop.ipc包下,存在客户端类Client和服务类Server。

Client类的类图机构,Cient类中包含了多个内部类。

HDFS源码分析(1)--RPC解析

Server类的类图结构

HDFS源码分析(1)--RPC解析

关于这两个类将在接下来重点讲解。