RPC ( Remote Procedure Call )
什么是RPC协议?
RPC 是 Remote Procedure Call 的缩写,中文是远程过程调用。
简单来说,RPC是一种计算机通信协议,它允许一个程序(客户端)调用另一个地址空间(通常是网络上的另一台计算机)中的子程序(服务器端)就像调用本地程序一样,而无需程序员显式地编写网络通信细节。
核心思想
RPC的目标是让分布式系统的开发变得更简单。它提供了一种透明的调用机制,使得开发者不必区分本地调用和远程调用。对开发者而言,调用一个远程服务的方法就像调用本地方法一样自然。
RPC的工作原理
- 定义接口 (Interface Definition Language - IDL): 首先,服务提供方(服务器)需要定义它提供哪些服务和方法,以及这些方法的参数和返回值类型。这通常通过接口定义语言(IDL) 来完成。在HDFS中,这个IDL的定义就是通过之前提到的Protocol Buffers的.proto文件来完成的,它不仅定义了数据结构,也隐含地定义了RPC方法。
- 生成存根 (Stub): IDL文件会被一个特殊的编译器(比如Protobuf编译器)编译,生成客户端和服务端所需的存根(Stub)代码。
- 客户端存根(Client Stub):负责将客户端的调用请求(方法名、参数)打包(Marshal/编码)成符合RPC协议的数据格式,并通过网络发送给服务器。它还会接收服务器的响应,并解包(Unmarshal/解码)数据,最后将结果返回给客户端程序。
- 服务端存根(Server Stub):负责监听客户端的请求,接收请求数据,解包请求信息,然后调用真正的服务实现类的方法,并将方法执行结果打包后发送回客户端。
- 消息传输与通信: 客户端存根通过底层网络传输协议(如TCP或UDP)将打包好的请求发送到服务器。服务器端存根接收请求后进行处理,并将结果通过网络返回给客户端。
RPC的整个流程就像这样: 客户端调用本地的客户端存根 → 客户端存根序列化请求并发送 → 服务器端存根接收并反序列化请求 → 服务器端调用实际的服务方法 → 服务方法返回结果 → 服务器端存根序列化结果并发送 → 客户端存根接收并反序列化结果 → 客户端接收到结果。
RPC协议在HDFS源码中的应用
HDFS作为一个高度分布式的系统,其各个组件之间需要频繁地进行网络通信。RPC协议是HDFS实现这种通信的基石。
- 客户端与NameNode的通信: 当HDFS客户端执行诸如创建文件、读取文件、列出目录、获取文件块位置等操作时,它实际上是通过RPC调用NameNode上暴露的服务接口。例如,
ClientProtocol定义了客户端与NameNode之间的所有RPC接口。 - DataNode与NameNode的通信: DataNode需要向NameNode注册、发送心跳报告(包含存储状态、数据块信息)、报告数据块完成状态等。这些都是通过RPC调用NameNode上的服务完成的。例如,
DatanodeProtocol定义了DataNode与NameNode之间的RPC接口。 - 客户端与DataNode的通信: 当客户端要读取或写入数据时,NameNode会告诉客户端数据块在哪些DataNode上。然后,客户端会直接通过RPC与这些DataNode进行通信,进行实际的数据传输。
HDFS中RPC协议的特点
- 基于TCP/IP:HDFS的RPC通常运行在TCP/IP之上,提供可靠的连接传输。
- 可插拔的序列化框架:HDFS的RPC层是可插拔的,允许选择不同的数据序列化框架。在较新的HDFS版本中,Protocol Buffers是其默认且主要使用的序列化机制。这就是为什么你会在学习HDFS源码时同时看到Protobuf和RPC。Protobuf负责把方法的参数和返回值变成可以在网络上传输的二进制数据,而RPC负责定义如何在网络上传输这些数据,并提供远程调用的抽象。
- 高并发和可扩展性:HDFS的RPC服务器设计考虑了高并发处理,能够同时处理大量来自客户端和DataNode的请求。
- 身份认证与安全性:HDFS的RPC还包含了身份认证和授权机制,确保只有合法用户和节点才能访问服务。
RPC与HTTP API的区别
理解RPC协议,很多人会自然地拿它与HTTP API (特别是RESTful API) 进行比较。它们都是实现分布式系统通信的方式,但设计理念和适用场景有所不同。
| 特性 | RPC (远程过程调用) | HTTP API (例如RESTful API) |
|---|---|---|
| 设计理念 | 动作/行为导向 (Action/Verb-centric):关注执行远程函数或过程。 | 资源导向 (Resource-centric):关注对资源的增删改查操作。 |
| 通信模型 | 客户端调用服务器上的函数/方法。 | 客户端通过标准HTTP方法(GET, POST, PUT, DELETE)对资源进行操作。 |
| 数据格式 | 通常使用紧凑的二进制格式(如Protobuf、Thrift),效率高。 | 通常使用文本格式(如JSON、XML),可读性好。 |
| 协议栈 | 可以直接运行在TCP之上,也可以封装在HTTP/2等之上。 | 基于HTTP协议,依赖HTTP的语义和状态码。 |
| 易用性/标准化 | 需要IDL定义,生成代码,相对复杂,但对开发者透明。 | 简单、标准化,浏览器可以直接访问,生态系统更成熟。 |
| 性能 | 通常更高,因为数据更紧凑,且可以保持长连接。 | 通常较低(相比于优化过的RPC),因为有HTTP头开销和短连接。 |
| 耦合度 | 相对紧耦合,客户端需要知道服务器提供的具体方法。 | 相对松耦合,客户端只需知道资源URI和HTTP方法。 |
| 典型应用 | 高性能、内部服务间通信(微服务),例如HDFS内部通信。 | 对外暴露API(Web API),与异构系统集成,浏览器访问。 |
HDFS选择RPC(并结合Protobuf)作为其核心通信协议,正是因为它需要极致的性能、效率和对底层数据结构的精细控制,这在处理海量数据和高并发访问的分布式文件系统场景下至关重要。

浙公网安备 33010602011771号