Hadoop3.2.1 【 HDFS 】源码分析 : RPC实现 [二] 概述&使用


 

RPC概述

RPC(Remote Procedure Call)即远程过程调用,是一种通过网络从远程计算机程序上请求服务的协议。RPC允许本地程序像调用本地方法一样调用远程计算机上的应用程序,其使用常见的网络传输协议(如TCP或UDP)传递RPC请求以及相应信息,使得分布式程序的开发更加容易。Hadoop作为分布式存储系统, 各个节点之间的通信和交互是必不可少的, 所以需要实现一套节点间的通信交互机制。

Hadoop实现了一套自己的RPC框架。采用了JavaNIO、Java动态代理以及protobuf等基础技术

RPC采用客户端/ 服务器模式, 请求程序就是一个客户端, 而服务提供程序就是一个服务器。 客户端首先会发送一个有参数的调用请求到服务器, 然后等待服务器发回响应信息。 在服务器端, 服务提供程序会保持睡眠状态直到有调用请求到达为止。 当一个调用请求到达后, 服务提供程序会执行调用请求, 计算结果, 向客户端发送响应信息, 然后等待下一个调用请求。 最后, 客户端成功地接收服务器发回的响应信息, 一个远程调用结束.

RPC框架工作原理示例图

  • client functions

    请求程序,会像调用本地方法一样调用客户端stub程序(如图中①),然后接受stub程序的响应信息(如图中⑩)

  • client stub

    客户端stub程序,表现得就像本地程序一样,但底层却会调用请求和参数序列化并通过通信模块发送给服务器(如图中②);客户端stub程序也会等待服务器的响应信息(如图中⑨),将响应信息反序列化并返回给请求程序(如图中⑩)

  • sockets

    网络通信模块,用于传输RPC请求和响应(如图中的③⑧),可以基于TCP或UDP协议

  • server stub

    服务端stub程序,会接收客户端发送的请求和参数(如图中④)并反序列化,根据调用信息触发对应的服务程序(如图中⑤),然后将服务程序的响应信息(如图⑥),并序列化并发回给客户端(如图中⑦)

  • server functions

    服务程序,会接收服务端stub程序的调用请求(如图中⑤),执行对应的逻辑并返回执行结果(如图中⑥)


Hadoop RPC实现

HadoopRPC实现方式跟上图一样,代码位于hadoop-common中的 org.apache.hadoop.ipc 包下.

Hadoop RPC框架主要由三个类组成: RPC、 Client和Server类。

RPC类用于对外提供一个使用Hadoop RPC框架的接口,

Client类用于实现RPC客户端功能,

Server类则用于实现RPC服务器端功能。 

在这里,我们先不写原理,先写一个demo, 然后跑起来. 测试一下效果.然后再说理论.

这个demo采用的是hadoop默认的RPC Engine :   WritableRpcEngine

采用 proto协议在定义接口协议&实现方面会不一样, 后面章节会有写这两个rpc engine的调度实例

1.定义接口协议

/**
 * 协议接口
 */
public interface ClicentNameNodeProtocol {
  //1. 定义协议的ID
  public static final long versionID = 1L;
  /**
   * 拿到元数据方法,协议通信前会访问元数据
   */
  public String getMetaData(String path);
}

2.实现接口协议

/**
 * 实现协议结构
 */
public class ClicentNameNodeImpl implements ClicentNameNodeProtocol {
  public String getMetaData(String path) {
    // 数据存放的路径,有多少块,块大小,校验和,存储在哪一台机器上
    return path + ":3 - {BLOCK_1,BLOCK_2,BLOCK_3....";
  }
}

3.创建Server服务, 并注册协议.启动RPC服务.


/**
 * 启动RPC服务
 */
public class Server {
  public static void main(String[] args) throws IOException {
    //1. 构建RPC框架
    RPC.Builder builder = new RPC.Builder(new Configuration());
    //2. 绑定地址
    builder.setBindAddress("localhost");
    //3. 绑定端口
    builder.setPort(7777);
    //4. 绑定协议
    builder.setProtocol(ClicentNameNodeProtocol.class);
    //5. 调用协议实现类
    builder.setInstance(new ClicentNameNodeImpl());
    //6. 创建服务
    RPC.Server server = builder.build();
    //7. 启动服务
    server.start();
  }
}

4.创建Client服务,请求数据接口

/**
 * 访问RPC服务
 */
public class Client {
  public static void main(String[] args) throws IOException {
    //1. 拿到RPC协议
    ClicentNameNodeProtocol proxy = RPC.getProxy(ClicentNameNodeProtocol.class, 1L,
        new InetSocketAddress("localhost", 7777), new Configuration());
    //2. 发送请求
    String metaData = proxy.getMetaData("/meta");
    //3. 打印元数据
    System.out.println(metaData);
  }
}

5.测试结果

        

参考:

https://blog.csdn.net/DiDi_Tech/article/details/100919314
Hadoop 2.X HDFS源码剖析 -- 徐鹏

发布了336 篇原创文章 · 获赞 846 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/zhanglong_4444/article/details/105591336
今日推荐