hadoop源码_Hadoop源码解析-RPCClient的实现

前言

在一个RPC系统中一定包含两个角色 Server/Client。本文重点介绍Hadoop系统中的RPC实现中的 RPC Client端实现。Hadoop绝大部分代码由Java实现,下面的Java类实现了RPC client的主要逻辑:

org

总览

在当前Hadoop的RPC Client架构中有三个重要的角色,RPCClient, Connection, Call

RPC Client: Hadoop应用在初始化RPC Client的时候需要初始化一些必要的配置参数例如链接超时时间(ConnectionTimeout)等,RPC Client 并不需要对网络链接进行初始化。

Connection: 每个RPC client 可以有多个Connection, 每个Connection代表特定的服务端TCP 链接,以及一些必要的配置参数。

Call: 在Connection建立的情况下,客户端可以利用这个已经建立的TPC连接反复发送RPC call, 每个RPC call代表一次从客户端到服务端的远程调用。

以上三者关系如下图所示,本文将结合部分源码在接下来的部分阐述RPC client的工作原理

84e04f98dbb6ccb4063b14dd01c6a753.png

建立Connection

在Client初始化完成以后,Client对象实质上无法得知其将要链接的服务端网络地址,因此在第一个RPC请求到达之前没有任何网络链接的产生。每一个RPC请求会指定服务端的网络地址,在请求到达以后Client对象首先检查是否已经存在这样的一个网络链接,如果存在的话则用之进行网络交互,否则新建一个。代码片段如下:

connection 

RPC Call的发送

RPC Client发送RPC request的主要入口函数是:

public 

在RPC Call到达以后,Connection选择立即发送该RPC Call, 并且暂时保存该RPC Call对象(此时Connection对象并没有立刻要求网络响应)。值得注意的是 Connection使用一个线程池来发送RPC Call。这个线程池的初始化代码如下:

synchronized 

这样初始化的线程池特点如下:

  1. 空闲时不会有线程驻留
  2. 线程的个数上线是Integer.MAX_VALUE
  3. 对于任何一个线程空闲时间超过60秒以后,会被回收。
public 

Rpc Call可以是同步的方式也可以是异步的方式。如果是异步方式,则构造一个Future,交给调用段去管理改Future的生命周期,该Future实质上是封装了同步获取RPC响应的函数。如果是同步调用,则直接调用该函数(阻塞当前线程,直到RPC响应)

if 

RPC Response 捕获

由于网络响应是不可预期的,因此函数getRpcResponse不能期望网络立即能得到网络的响应,hadoop采用了wait/notify的方式来实现基于通知机制的RPC响应。简单来说,函数getRpcResponse先行调用 call对象的wait()方法阻塞当前线程(假设为t),等到有网络响应是该call对象的notify方法会被调用,唤起线程t。参考函数:

org

事实上, Connection继承自Thread类,其run方法的实现实质上是持续的从网络上读取数据。根据数据的返回内容解析出响应的callId,并调用与之对应的call对象的notify方法。参考函数:

org.apache.hadoop.ipc.Client$Connection::run

网络输入流-InputStream

当一个网络请求发送给Server端以后,client客户端的行为由两个参数控制:RpcTimeout和PingInterval,行为如下

  1. 尝试从网络读出数据,如果读到至少一个字节则开始解析网络响应,如果得到一个SocketTimeoutException则转2。值得注意的是Client的超时时间是由PingInterval决定的,所以一旦客户端收到这个异常,则可断言网络上至少已经等待PingInterval的时长。
  2. 检查等待时间是不是超过RpcTimeout,如果超过,则把SocketTimeoutException抛给调用端;如果没有,则发送一个Ping包到Server端.

注: PingInterval由参数:ipc.ping.interval指定;RpcTimeout由ipc.client.rpc-timeout.ms指定。需要指出的是:如果RpcTimeout设置为0,如果Server端迟迟不响应,那么client端将会无休止的sendPing()直到网络响应。

Hadoop靠一个自己封装的PingInputStream实现这个效果。

public 

结论

一个RPC Client可以管理到多个RPC server的TCP链接,在TCP建立起来以后多个Call可以复用链接。RPC的响应采用异步通知的方式。封装的PingInputStream实现了在超时时间内周期性发送ping包的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值