hbase 客户端_HBase源码:网络通信篇

8a3a1b69e68c0482a3828fef3298625a.png

导读

在分布式存储系统中,节点间的通信是很重要的组成部分。如果不了解系统中的通信机制,就无法真正理解一套完整的读写流程。由于HBase年代久远(1.2.0版本),暂时使用的还是java原生的NIO,并没有使用Netty之类的框架。

本篇就来介绍下HBase中基于NIO的RPC通信。

1 RPC=protobuf+nio

HBase基于protobuf+nio实现rpc:基于protobuf预定义消息格式,基于nio做消息的传输以及服务器编写。

ef53a8bcc865e17fe0e75f3910bb7006.png

protobuf可以简单的理解成一种格式定义,定义好可以自动生成对应的接口类。开发者需要在客户端和服务端生成对应的实现类,客户端负责封装接口参数,通过socket发送到远程服务提供方;服务端负责实现接口的具体执行过程,在服务器上执行真正的操作,返回结果。这样调用者就可以像调用本地方法一样调用远程方法了。

61b726795579170bdceef5331149307b.png

HBase的服务端采用的是标准的Reactor模型:

Listener相当于acceptor,封装了Reader线程池,用于接收客户端的连接;

Scheduler中有不同的线程池用于专门处理任务;

Responder负责向客户端返回执行结果。

2 客户端详解

HBase的客户端与传统的数据库连接池类似,也是在内存中维护客户端与各个存储节点的连接,并配置对应的存活时间,存活时间范围内连接是可以复用的(这里的复用是指,不需要单独进行TCP的三次握手;通用的header,协议格式等都可以直接复用;直接调用对应的OutPutStream.write方法执行写操作就可以了)。因此如果想复用连接,就需要在逻辑业务上区分相同RegionServer的不同请求类型,HBase在protobuf中定义了不同的请求类型,如:Get,Mutate,Scan,Bulk,multi等,具体的可以参考protobuf中的定义。

总结来说,相同的RegionServer、相同的请求类型、存活时间范围内都可以共享连接,不需要重新建立连接。

整体的流程如下:当客户端需要发送请求时,先判断是否已经存在有效连接,如果不存在则重新建立。获得连接后执行发送操作,并阻塞等待。如果开启了异步发送,则会发送到另一个发送列表中,会有专门的线程执行发送操作。

f5d1d9ddfefd8146d96e9b5694e5f549.png

客户端中比较重要的组件主要有下面几个:

RpcClientImpl:客户端主要实现类,内部维护了Connection的Map引用,其中Map的key由用户、方法服务名、目标地址等组成。

Connection:代表一次连接,内部封装了Socket。

0d599e4cd0b6e122ea9af58c8967dd0c.png

整体流程如下:

1 当调用Callable时,获得RPC实例,并获得RpcClient实现类

2 调用Rpc的get方法

3 调用RpcClientImpl的call方法

4 获得连接Connection

5 执行发送

6 阻塞等待结果

3142e0582255e00e73de059d35514900.png

3 服务端详解

服务端的设计明显就要复杂很多,首先是Rpc的服务器都封装在RpcServer中,当HRegionServer启动时,会执行初始化。

6691d0d575e853564e42f0ef9e54ebb1.png

Server中包含三个主要的部分:

Listener,负责监听消息,内部封装Reader线程池异步接收处理、

Responder,负责回复、

RpcScheduler,负责根据不同的策略分发任务

8d7fb22b2093d6bde2c585c84f5cbd4e.png

整体流程如下:

1 HRegionServer启动,开启RsRpcServerices服务

2 初始化RpcServer,初始化内部组件:Listener、scheduler、responder等

3 listener接收请求,内部Reader线程池轮训处理,执行readprocess,交给scheduler进行分发

4 scheduler分发执行任务,调用rpcserver的call方法

5 调用rsrpcservices中的实现方法,执行处理

6 结果放入返回队列中,返回

6e6fad397991d94efcee3c995a672953.png

4 总结

第一次阅读NIO相关的服务器编程,关于NIO的技术细节还不是很熟练,因此有很多Selector互相调用触发的代码看的有点蒙。不过总体的流程梳理的差不多,这些细节也就不过多花精力了。

总结一下:对于HBase的Client端,连接使用NIO的Socket实现,相同主机相同类型的请求复用连接,阻塞等待连接返回结果;对于HBase的Server端,使用Reader线程池异步接收消息执行读取操作;使用Scheduler进行消息的分发处理;使用Responder合并处理结果,批量返回。

往期推荐:

HBase源码:如何设计高效的分布式客户端​mp.weixin.qq.com
526b5f75733688e677000fc47024ff3d.png
HBase源码:Region的定位与优化​mp.weixin.qq.com
30cfb7764e1d20ce854c19f14ff86a4c.png

ca726c1b5e730ee8c2d07b5bceaa18e9.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值