HBase的RPC通信功能主要基于Protobuf和NIO这两个组件来实现,在通信管道上选择的是protobuf对外声明的BlockingRpcChannel(阻塞式),其callBlockingMethod方法决定了客户端与服务端的交互行为,比如采用什么样的方法进行通信以及通信报文的格式规则都是通过该方法来描述的。
HBase对外声明了BlockingRpcChannelImplementation实现类用于实现BlockingRpcChannel接口的业务逻辑,其在通信方式的选择上采用的是Socket通信,在通信的服务端通过RpcServer来构建ServerSocket,而在客户端使用RpcClient来构建与服务端通信的Socket,按照功能职责的不同,RpcServer可划分成3大组件,其中:
-
Listener负责监听客户端的连接请求
在Listener的内部主要封装着一个ServerSocketChannel以及多个Reader线程,其中ServerSocketChannel主要负责接收客户端的连接请求,请求被响应前,会暂存于等待队列中,等待队列的长度通过hbase.ipc.server.listen.queue.size参数来设置(默认为128)。针对每个已建立的连接,系统还会实时检测其空闲时间,如果空闲时间超过2秒(即2秒内客户端没有再次通过该连接来发送请求,并且之前的请求操作已经处理完毕),系统会将该连接进行关闭,时间阀值是通过hbase.ipc.client.connection.maxidletime参数来控制的。
当请求信息到达后,其会派遣合适的Reader进行读取(基于轮训的方式来使每个Reader的负载能够均衡),Reader线程的数量是通过hbase.ipc.server.read.threadpool.size参数来指定的,默认为10个,线程启动后会进入阻塞状态直至客户端请求操作的到来。客户端向服务端发送的通信报文是按照一定格式进行组织的,如图所示:
-
当客户端与服务端进行初次握手时,其会向服务端发送RPCHeader报文,以便服务端能够对客户端的连接请求做校验处理。
如果校验结果满足以下规则,说明该请求操作是合法的:
(1)前4个字节信息为HBas;
(2)第5个字节(VERSION信息)的值为0;
(3)在没有启用security的情况下(hbase.security.authentication属性值不为kerberos),第6个字节的值为80。
-
接着,客户端会向服务端发送ConnectionHeader报文,通过它来封装客户端所请求的服务。
ConnectionHeader是通过使用protobuf来完成序列化处理的,其protocol声明如下:
message ConnectionHeader {
optional UserInformation user_info = 1;
optional string service_name = 2;
optional string cell_block_codec_class = 3;
optional string cell_block_compressor_class = 4;
}
服务端收到该请求消息之后,可通过其service_name属性来判断客户端所要访问的服务名称,从而定位到具体的服务。
-
确定了具体的服务之后,客户端便可持续向服务端发送Request报文,通过它来定位将要执行服务的哪一个方法。
方法名称是通过RequestHeader来封装的,其属于Request报文的一部分,如图所示:
RequestHeader同样是采用protobuf进行序列化处理,其protocol声明如下
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)