hadoop RPC

本文详细介绍了Hadoop RPC的客户端和服务端架构。客户端采用阻塞Socket方式,通过线程池管理Connection;服务端则利用非阻塞Socket和Selector处理大量并发请求,通过线程池读取和响应数据。

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

 

hadoop RPC

 

 

 上边是一张hadoop RPC很粗糙的类图,只包含其中主要的类关系

 

  hadoop RPC的总架构是

    Client端使用的是阻塞的Socket,

    Client的Connection内部类负责Socket的操作

        setupIOStream方法建立socket连接

        sendParam(call)方法传输客户端socket数据

        receiveResponse会阻塞等待服务端的response

 

   客户端Client没有使用NIO, 而是使用Connection线程的对象池,以ConnectionID为主键。

 

   -------------------------------------------------------------------------------------------------------------

 

Server端使用的是非阻塞的Socket 大量使用Selector

 

Server的Listener内部类负责接收Socket请求,并开启reader的线程池,在需要读取数据时,wakeup selector--唤醒读线程;Listener中的Reader内部类负责读取socket数据(具体的操作还是在Listener和Connection中,可见reader这个内部类是因为效率而后加的),读取的数据也包括hadoop的头数据,封装为Call对象,放到Server下的队列中

 

Server的Handler内部类负责获取队列中的Call对象,并且调用处理类Call,返回处理后的的value,并且调用doRespond,wakeup-selector--唤醒写线程

 

Server的Responder内部类负责写入相应信息。

 

Server只负责启动listener,handler,responder各个线程,让其各执其责。

他并不是继承与Thread,但是其包含大量Thread,所有的服务操作都要在这一个Server中进行,个人认为这也暴漏了hadoop架构的缺陷

public synchronized void start() {  
  responder.start();  //启动responder  
  listener.start();   //启动listener  
  handlers = new Handler[handlerCount];  
    
  for (int i = 0; i < handlerCount; i++) {  
    handlers[i] = new Handler(i);  
    handlers[i].start();   //逐个启动Handler  
  }  
}

 

 

   

 

 

 

 

 

### 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、付费专栏及课程。

余额充值