Hadoop的RPC

本文深入解析RPC(远程过程调用)的基本概念、工作原理及其在Hadoop中的应用。详细介绍了RPC如何通过网络实现远程函数调用,以及Hadoop RPC如何构建于TCP/IP之上,实现高效的数据处理和分布式计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 关于RPC

(1)RPC的概念

   RPC(Remote Procedure Call)--远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如;TCP或者UDP,为通信程序之间携带信息数据,在OSI网络通信模型中,RPC跨越了传输层应用层。RPC使得开发包括网络分布式程序在内的应用程序更加容易。

(2)OSI网络七层模型

Hadoop的RPC
第一层:物理层。这一层主要就是传输这些二进制数据。
第二层:链路层。将上面的网络层的数据包封装成数据帧,便于物理层传输;
第三层:网络层。定义网络设备间如何传输数据;
第四层:传输层。管理着网络中的端到端的数据传输;
第五层:会话层。管理用户的会话,控制用户间逻辑连接的建立和中断;
第六层:表示层。定义不同的系统中数据的传输格式,编码和解码规范等;
第七层:应用层。定义了用于在网络中进行通信和传输数据的接口;

(3)RPC工作机制

   RPC 采用客户机/服务器模式:请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在 服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进 程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收 答复信息,获得进程结果,然后调用执行继续进行。
   通俗的说: RPC 是指远程过程调用,也就是说两台服务器 A,B,一个应用部署在 A 服务器, 想要调用 B 服务器提供的函数和方法,由于不在一个内存空间,不能直接调用,需要通过 网络来表达调用的语义和传达调用的数据。也可以理解成不同进程之间的服务调用。
     Hadoop的RPC
实现的具体步骤
  第一(通讯问题):主要是通过在客户端和服务器之间建立 TCP 连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
  第二(寻址问题):A 服务器上的应用怎么告诉底层的 RPC 框架,如何连接到 B 服务器(如主机或 IP 地址)以及特定的端口,方法的名称以及名称是什么,这样才能完成调用。
  第三(方法参数的网络传递):当 A 服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如 TCP 传递到 B 服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制 的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制 发送给 B 服务器。
  第四(反序列化):B 服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中 的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
  第五(返回值):返回值还要发送回服务器 A 上的应用,也要经过序列化的方式发送,服务器 A 接到 后,再反序列化,恢复为内存中的表达方式,交给 A 服务器上的应用

(4)RPC的作用

   - 让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务,并且屏蔽编程语言的差异性。
   - 让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性
   - 在客户端 A 上来说,会生成一个服务器 B 的代理。(总结)

(5)JAVA中流行的RPC框架

  RMI(远程方法调用):JAVA 自带的远程方法调用工具,不过有一定的局限性,毕竟是 JAVA 语言最开始时的设计, 后来很多框架的原理都基于 RMI。
  Hessian(基于 HTTP 的远程方法调用):基于 HTTP 协议传输,在性能方面还不够完美,负载均衡和失效转移依赖于应用的负载均衡 器,Hessian 的使用则与 RMI 类似,区别在于淡化了 Registry 的角色,通过显示的地址调用, 利用 HessianProxyFactory 根据配置的地址 create 一个代理对象,另外还要引入 Hessian 的 Jar 包。
  Dubbo(阿里开源的基于 TCP 的 RPC 框架):基于 Netty 的高性能 RPC 框架。
       Hadoop的RPC

2. Hadoop的RPC

(1)相关概念介绍

  同其他 RPC 框架一样,Hadoop RPC 分为四个部分:
   - 序列化层:Client 与 Server 端通信传递的信息采用了 Hadoop 里提供的序列化类或自定义 的 Writable 类型;
   - 函数调用层:Hadoop RPC 通过动态代理以及 Java 反射实现函数调用;
   - 网络传输层:Hadoop RPC 采用了基于 TCP/IP 的 socket 机制;
   - 服务器端框架层:RPC Server利用Java NIO以及采用了事件驱动的I/O模型,提高RPC Server 的并发处理能力;
  Hadoop RPC 在整个 Hadoop 中应用非常广泛,Client、DataNode、NameNode 之间的通讯全 靠它了。例如:我们平时操作 HDFS 的时候,使用的是 FileSystem 类,它的内部有个 DFSClient 对象,这个对象负责与 NameNode 打交道。在运行时,DFSClient 在本地创建一个 NameNode 的代理,然后就操作这个代理,这个代理就会通过网络,远程调用到 NameNode 的方法, 也能返回值。
        Hadoop的RPC

(2)涉及到的相关技术点

  - 代理:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,代理对 象对客户隐藏了实际对象。目前 Java 开发包中提供了对动态代理的支持,但现在只支持对 接口的实现。
  - 反射:动态加载类
  - 序列化:用于将对象进行网络传输
  - NIO:非阻塞的异步

(3)HadoopRPC的构建步骤

  - 定义PRC协议:RPC 协议是客户端和服务器端之间的通信接口,它定义了服务器端对外提供的服务接口。
  - 实现PRC协议:Hadoop RPC 协议通常是一个 Java 接口,用户需要实现该接口。
  - 构造和启动RPC server :直接使用静态类 Builder 构造一个 RPC Server,并调用函数 start()启动该 Server。
  - 构建RPC client 并发送请求:使用静态方法 getProxy 构造客户端代理对象,直接通过代理对象调用远程端的方法。

(3)HadoopRPC 入门案例

  1.定义协议
//定义PRC协议

public interface BussinessProtocol {
    //在client和server通信的时候,需要版本一致
    long versionID=11511056056L;
    void mkdir(String name);
    void hello(String message);
}

  2.实现协议

//实现RPC协议
public class BussinessProtocolImpl implements BussinessProtocol {

    @Override
    public void mkdir(String name) {
        System.out.println("创建了:"+name);
    }

    @Override
    public void hello(String message) {
        System.out.println("你好"+message);
    }
}

  3.构建服务端

//构建RPCserver并启动服务端
public class MyRPCServer {
    public static void main(String[] args) {
        RPC.Server server = null;
        try {
            /**
             * 在new RPC.Builder:传入Configuration对象
             *  setProtocol(BussinessProtocol.class):设置协议类
             *  setInstance(new BussinessProtocolImpl()):协议实现类对象
             *  setBindAddress("localhost"):绑定的主机
             *  setPort(6789):设置端口
             */
            server = new RPC.Builder(new Configuration())
                    .setProtocol(BussinessProtocol.class)
                    .setInstance(new BussinessProtocolImpl())
                    .setBindAddress("localhost")
                    .setPort(6666)
                    .build();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //启动服务
        server.start();
    }
}

  4.构建客户端
//构建 RPC Client 并发出请求

public class MyRPCClient {
    public static void main(String[] args) {
        try {
            /**
             * 获取代理类对象,客户端通过这个代理可以调用服务端的方法进行逻辑处理:
             * Class<T> protocol 协议类的class对象
             * long clientVersion:版本
             * InetSocketAddress addr:主机端口
             * Configuration conf:配置文件对象
             */
            BussinessProtocol proxy = RPC.getProxy(BussinessProtocol.class,
                    BussinessProtocol.versionID,
                    new InetSocketAddress("localhost", 6666),
                    new Configuration());
            //在客户端调用了服务端的代理对象的方法
            //其实正真的代码在服务端运行
            proxy.hello("zs");
            proxy.mkdir("/root/zy");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  5.启动测试
启动服务端:运行:
Hadoop的RPC
启动客户端 运行:
Hadoop的RPC
观察服务端console:
Hadoop的RPC

转载于:https://blog.51cto.com/14048416/2337498

### Hadoop RPC 工作机制 Hadoop RPC(远程过程调用)是一种允许不同节点之间相互通信的技术,主要用于分布式文件系统的操作。通过这种技术,客户端可以像本地方法一样调用服务器端的方法。 #### 建立连接 当Hadoop客户端向NameNode发起RPC请求时,首先要建立到服务端的Socket连接[^3]。这一阶段涉及到网络地址解析和服务端口定位等工作。为了提高效率并减少开销,通常会采用长连接的方式保持一段时间内的多次交互而不必每次都重新创建新的TCP链接。 #### 序列化与反序列化 数据在网络上传输之前需要被转换成字节流形式,即所谓的“序列化”。而在接收方则要执行相反的操作——把收到的数据还原回原始对象结构,这称为“反序列化”。对于Hadoop而言,其内部实现了自定义的Writables接口来支持高效的数据交换格式[^1]。 #### 请求处理流程 一旦建立了稳定可靠的通信链路之后,接下来就是实际的消息传递环节了: - 客户端发送带有参数的具体命令给目标机器上的指定程序; - 对应的服务进程接收到消息后依据协议规定解析出意图,并据此做出响应动作; - 执行完毕后再将结果封装好返回给发出指令的一方; 整个过程中还包含了错误检测、超时控制等功能以确保可靠性[^2]。 ```java // 创建代理实例用于访问远程服务 InetSocketAddress addr = new InetSocketAddress("localhost", port); MyProtocol proxy = RPC.getProxy(MyProtocol.class, MyProtocol.versionID, addr, conf); // 调用远程方法 long result = proxy.myMethod(param1,param2); ``` 上述代码展示了如何使用`RPC.getProxy()`函数获取一个能够代表远端实体的对象引用,进而可以通过它来进行跨主机边界的方法调用。 ### 解决方案针对常见问题 - **性能瓶颈** 如果发现系统吞吐量不足或者延迟过高,则可能是由于频繁地打开关闭socket造成的资源浪费所致。此时应该考虑调整配置项使得尽可能多地重用已存在的连接而不是每次都要新建断连。 - **版本不兼容** 当遇到因API变更引起的老版客户端无法正常工作的情况时,建议引入向前/向后的兼容策略,比如保留旧签名的同时增加新特性标记位以便区分不同的行为模式。 - **安全性隐患** 面对潜在的安全威胁如中间人攻击等问题,务必启用SSL/TLS加密传输通道并对所有入站流量实施严格的认证授权措施防止未授权访问发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值