写点什么

深入理解 HDFS(三):Hadoop RPC

作者:冰心的小屋
  • 2023-08-08
    北京
  • 本文字数:1958 字

    阅读完需:约 6 分钟

深入理解 HDFS(三):Hadoop RPC

TCP/IP 是一种面向连接的、可靠的、基于字节流的传输层通信协议,Hadoop RPC 通信协议是建立在 TCP/IP 协议之上,自己实现的一套 RPC 协议。那 Hadoop RPC 是如何从设计到实现的呢,以下是我个人理解,不对之处欢迎指出。

1. RPC 目的

在使用面向对象语言编程时,如果想使用某个类的具体功能,需要先创建这个类的对象,之后调用对象提供该功能的方法,一切看起来非常自然。由此推断 RPC 也是同样目的:调用远程服务可以像调用本地对象的方法那样简单,忽略底层的通信模型。专注于功能的实现。

2. 抽象设计

服务端提供服务,客户端调用服务,请求的调用如果能委托一个第三方 Invoker,那么通信的角色有:

  • Client:获取服务端提供的功能;

  • Invoker:通过某种机制将 Client 请求传递给 Server,同时 Server 处理后将结果返回给 Client;

  • Server:提供不同类型的一系列功能。


Server 需要解析 Client 发送的各种请求,处理后需要将相应结果返回给 Client,所以调用的流程应该是:

Client -> 请求对象创建 -> 请求对象序列化 -> Invoker 调用 -> 请求对象反序列化 -> Server 处理请求 -> 响应对象创建 -> 响应对象序列化 -> Invoker 中转 -> 响应对象反序列化 -> Client 解析响应


而在 HDFS 中类的设计:

  • Call:Client 创建的请求;

  • Message:Server 处理请求返回的响应结果;

  • RpcWritable:序列化和反序列化依赖的中间结果。

3. 具体实现

在序列化和反序列化的开源项目中,Google 的 Protobuf 首屈一指,那么 Protobuf 用于 RPC 协议的实现是一个不错的选择,下面是 Hadoop RPC 的大致实现:


  • 实际请求和响应都使用 Protobuf 对象,请求对应着 RequestProto,响应对应着 ResponseProto;

  • 如果 Client 端基于 DistributedFileSystem,那么请求最终会通过 DFSClient 发送;

  • ProtobufRpcEngine2 的内部类 ProtoBufRpcInvoker 实现了 RpcInvoker,获取实际请求的处理类并转发请求;

  • Server 最终转化成多个 BlockingService,每个 BlockingService 提供某类具体功能。

4. Hadoop RPC 协议格式

Hadoop RPC 的协议主要由三部分组成:

  1. 头信息:用以标识此次是 RPC 请求,前 4 个字节是魔数 hrpc;

  2. 连接上下文信息:请求头 + 具体内容;

  3. 实际请求数据:Protobuf 请求头和数据。


为了查看实际协议内容,写了一段用于获取 HDFS 目录详情的代码,先前已经创建了 /tmp 目录。

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileStatus;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;
public class Starter { public static void main(String[] args) throws Exception { Configuration configuration = new Configuration(); System.setProperty("HADOOP_USER_NAME", "5CC99CC1"); configuration.set("fs.defaultFS", "hdfs://tx:8020");
FileSystem fileSystem = FileSystem.get(configuration); FileStatus fileStatus = fileSystem.getFileStatus(new Path("/tmp")); System.out.println(fileStatus); }}
复制代码


程序执行时,服务端使用 tcpdump 进行抓包,之后将包下载到本地,用 wireshark 打开分析:


101.241.83.234 是我的客户端 IP,10.0.16.6 是 Namenode IP,前三行是 TCP 的三次握手,第 4 行是通过调用fileSystem.getFileStatus 发送的请求, TCP 的 data (200 bytes) 就是此次发送的 bytes,下面让我们根据协议格式的定义,结合实际数据来分析:

// h  r  p  c:4   68 72 70 63// version, service class, AuthProtocol:4 + 3 = 7   09 00 00// IpcConnectionContextProto 字节数:7 + 4 = 11   00 00 00 54 (84)// RpcRequestHeader 第1个字节为长度,紧跟着26个字节:11 + 1 + 26 = 38   1a (26)   08 02 10 00 18 05 22 10 7a 9a   87 d6 b3 c9 40 fe 99 ed 3e 79   e6 4a b4 42 28 01// IpcConnectionContext 第1个字节为长度,紧跟着26个字节56个字节:38 + 1 + 56 = 95   38 (56)   12 06 0a 04 72 6f 6f 74 1a 2e   6f 72 67 2e 61 70 61 63 68 65   2e 68 61 64 6f 6f 70 2e 68 64   66 73 2e 70 72 6f 74 6f 63 6f   6c 2e 43 6c 69 65 6e 74 50 72   6f 74 6f 63 6f 6c// Protobuf objects  的大小:95 + 4 = 99   00 00 00 65 (101)// Protobuf header 的大小:99 + 1 + 26 = 126   1a (26)   08 02 10 00 18 00 22 10 7a 9a   87 d6 b3 c9 40 fe 99 ed 3e 79   e6 4a b4 42 28 00// 剩下的正好74个字节:126 + 74 = 200   3e 0a 0a 67 65 74 4c 69 73 74   69 6e 67 12 2e 6f 72 67 2e 61   70 61 63 68 65 2e 68 61 64 6f   6f 70 2e 68 64 66 73 2e 70 72   6f 74 6f 63 6f 6c 2e 43 6c 69   65 6e 74 50 72 6f 74 6f 63 6f   6c 18 01 0a 0a 04 2f 74 6d 70   12 00 18 01
复制代码


发布于: 刚刚阅读数: 4
用户头像

分享技术上的点滴收获! 2013-08-06 加入

一杯咖啡,一首老歌,一段代码,欢迎做客冰屋,享受编码和技术带来的快乐!

评论

发布
暂无评论
深入理解 HDFS(三):Hadoop RPC_hdfs_冰心的小屋_InfoQ写作社区