目录
背景
HBase的RPC Protocol
?HBase-RPC实现机制分析
?思考
参考文献:
首页 数据库 mysql教程 深入分析HBase RPC(Protobuf)实现机制

深入分析HBase RPC(Protobuf)实现机制

Jun 07, 2016 pm 04:31 PM
hbase protobuf rpc 实现 机制 深入分析

背景 在HMaster、RegionServer内部,创建了RpcServer实例,并与Client三者之间实现了Rpc调用,HBase0.95内部引入了Google-Protobuf作为中间数据组织方式,并在Protobuf提供的Rpc接口之上,实现了基于服务的Rpc实现,本文详细阐述了HBase-Rpc实现细节。 HBase

背景

在HMaster、RegionServer内部,创建了RpcServer实例,并与Client三者之间实现了Rpc调用,HBase0.95内部引入了Google-Protobuf作为中间数据组织方式,并在Protobuf提供的Rpc接口之上,实现了基于服务的Rpc实现,本文详细阐述了HBase-Rpc实现细节。

HBase的RPC Protocol

?在HMaster、RegionServer内部,实现了rpc 多个protocol来完成管理和应用逻辑,具体如下protocol如下:

HMaster支持的Rpc协议:
MasterMonitorProtocol,Client与Master之间的通信,Master是RpcServer端,主要实现HBase集群监控的目的。

MasterAdminProtocol,Client与Master之间的通信,Master是RpcServer端,主要实现HBase表格的管理。例如TableSchema的更改,Table-Region的迁移、合并、下线(Offline)、上线(Online)以及负载平衡,以及Table的删除、快照等相关功能。

RegionServerStatusProtoco,RegionServer与Master之间的通信,Master是RpcServer端,负责提供RegionServer向HMaster状态汇报的服务。

RegionServer支持的Rpc协议:

ClientProtocol,Client与RegionServer之间的通信,RegionServer是RpcServer端,主要实现用户的读写请求。例如get、multiGet、mutate、scan、bulkLoadHFile、执行Coprocessor等。

AdminProtocols,Client与RegionServer之间的通信,RegionServer是RpcServer端,主要实现Region、服务、文件的管理。例如storefile信息、Region的操作、WAL操作、Server的开关等。

(备注:以上提到的Client可以是用户Api、也可以是RegionServer或者HMaster)

深入分析HBase RPC(Protobuf)实现机制


?HBase-RPC实现机制分析

RpcServer配置三个队列:

1)普通队列callQueue,绝大部分Call请求存在该队列中:callQueue上maxQueueLength为${ipc.server.max.callqueue.length},默认是${hbase.master.handler.count}*DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER,目前0.95.1中,每个Handler上CallQueue的最大个数默认值(DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER)为10。

2)优先级队列: PriorityQueue。如果设置priorityHandlerCount的个数,会创建与callQueue相当容量的queue存储Call,该优先级队列对应的Handler的个数由rpcServer实例化时传入。

3)拷贝队列:replicationQueue。由于RpcServer由HMaster和RegionServer共用,该功能仅为RegionServer提供,queue的大小为${ipc.server.max.callqueue.size}指定,默认为1024*1024*1024,handler的个数为hbase.regionserver.replication.handler.count。

RpcServer由三个模块组成:

Listener ===Queue=== Responder

?深入分析HBase RPC(Protobuf)实现机制

这里以HBaseAdmin.listTables为例,分析一个Rpc请求的函数调用过程:

1) RpcClient创建一个BlockingRpcChannel。

2)以channel为参数创建执行RPC请求需要的stub,此时的stub已经被封装在具体Service下,stub下定义了可执行的rpc接口。

3)stub调用对应的接口,实际内部channel调用callBlockingMethod方法。

RpcClient内实现了protobuf提供的BlockingRpcChannel接口方法callBlockingMethod,

? @Override
<span style="color: #000000; font-weight: bold;">public</span> Message callBlockingMethod<span style="color: #009900;">&#40;</span><span style="color: #003399;">MethodDescriptor</span> md, RpcController controller,
Message param, Message returnType<span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">throws</span> ServiceException <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">rpcClient</span>.<span style="color: #006633;">callBlockingMethod</span><span style="color: #009900;">&#40;</span>md, controller, param, returnType, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ticket</span>,
<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">isa</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">rpcTimeout</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
登录后复制

通过以上的实现细节,最终转换成rpcClient的调用,使用MethodDescriptor封装了不同rpc函数,使用Message基类可以接收基于Message的不同的Request和Response对象。

4)RpcClient创建Call对象,查找或者创建合适的Connection,并唤醒Connection。

5)Connection等待Call的Response,同时rpcClient调用函数中,会使用connection.writeRequest(Call call)将请求写入到RpcServer网络流中。

6)等待Call的Response,然后层层返回给更上层接口,从而完成此次RPC调用。

RPCServer收到的Rpc报文的内部组织如下:

Magic

(4Byte)

Version

(1字节)

验证方法

(1字节)

连接

标题长度

(4字节)

连接头

请求

“HBas”

验证 RpcServer 的 CURRENT_VERSION

与RPC报文一致

目前支持三类:

AuthMethod.SIMPLE

AuthMethod.KERBEROS

AuthMethod.DIGEST

RPC.proto 定义
RPCProtos.ConnectionHeader
消息连接头 {
可选的用户信息 userInfo = 1;
可选字符串 serviceName = 2;
// 单元块编解码器,我们将使用通过可选单元块发送。服务器抛出异常
// 如果无法处理。
可选字符串 cellBlockCodecClass = 3 [默认 = "org.apache.hadoop.hbase.codec.KeyValueCodec"];
// 如果单元块被压缩,我们将使用压缩器。?如果不支持,服务器将抛出异常。
// 类必须实现 hadoop 的 CompressionCodec 接口
可选字符串 cellBlockCompressorClass = 4;
}
序列化之后的数据

整个Request存储是经过编码之后的字节阵列,包括以下几个部分:

RequestHeaderLength(RawVarint32)

RequestHeader

ParamSize(RawVarint32)

Param

CellScanner

RPC.proto定义:
message RequestHeader {
// Monotonically increasing callId to keep track of RPC requests and their response
optional uint32 callId = 1;
optional RPCTInfo traceInfo = 2;
optional string methodName = 3;
// If true, then a pb Message param follows.
optional bool requestParam = 4;
// If present, then an encoded data block follows.
optional CellBlockMeta cellBlockMeta = 5;
// TODO: Have client specify priority
}
序列化之后的数据
并从Header中确认是否存在Param和CellScanner,如果确认存在的情况下,会继续访问。

Protobuf的基本类型Message,
Request的Param继承了Message,
这个需要获取的Method类型决定。

RequestHeaderLength(RawVarint32) 请求标头 参数大小(RawVarint32) 参数 细胞扫描仪 RPC.proto定义: 消息请求标头 { // 单调递增的 callId 来跟踪 RPC 请求及其响应 可选 uint32 callId = 1; 可选 RPCTInfo traceInfo = 2; 可选字符串 methodName = 3; // 如果为 true,则后面跟着一个 pb 消息参数。 可选 bool requestParam = 4; // 如果存在,则后面跟着一个编码数据块。 可选 CellBlockMeta cellBlockMeta = 5; // TODO: 让客户端指定优先级 } 序列化之后的数据 并从Header中确认是否存在Param和CellScanner,如果确认存在的情况下,会继续访问。 Protobuf 的基本类型消息, 请求的参数继承了消息, 这个需要获取的方法类型决定。

从功能上讲,RpcServer上包含了三个模块,

1)Listener。包含了多个Reader线程,通过Selector获取ServerSocketChannel接收来自RpcClient发送来的Connection,并从中重构Call实例,添加到CallQueue队列中。

?”IPC Server listener on 60021″ daemon prio=10 tid=0x00007f7210a97800 nid=0x14c6 runnable [0x00007f720e8d0000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked (a sun.nio.ch.Util$2)
- locked (a java.util.Collections$UnmodifiableSet)
- locked (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
at org.apache.hadoop.hbase.ipc.RpcServer$Listener.run(RpcServer.java:646)

2)Handler。负责执行Call,调用Service的方法,然后返回Pair

“IPC Server handler 0 on 60021″ daemon prio=10 tid=0x00007f7210eab000 nid=0x14c7 waiting on condition [0x00007f720e7cf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for? (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:399)
at org.apache.hadoop.hbase.ipc.RpcServer$Handler.run(RpcServer.java:1804)

3) Responder。负责把Call的结果返回给RpcClient。

?”IPC Server Responder” daemon prio=10 tid=0x00007f7210a97000 nid=0x14c5 runnable [0x00007f720e9d1000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked (a sun.nio.ch.Util$2)
- locked (a java.util.Collections$UnmodifiableSet)
- locked (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.doRunLoop(RpcServer.java:833)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.run(RpcServer.java:816)

RpcClient为Rpc请求建立Connection,通过Connection将Call发送RpcServer,然后RpcClient等待结果的返回。

?思考

1)为什么HBase新版本使用了Protobuf,并实现RPC接口?

HBase是Hadoop生态系统内重要的分布式数据库,Hadoop2.0广泛采用Protobuf作为中间数据组织方式,整个系统内Wire-Compatible的统一需求。

2)HBase内部实现的Rpc框架对于服务性能的影响?

目前使用Protobuf作为用户请求和内部数据交换的数据格式,采用更为紧缩编码格式,能够提高传输数据的效率。但是,有些优化仍然可以在该框架内探索:

实现多个Request复用Connection(把多个短连接合并成一个长连接);

在RpcServer内创建多个CallQueue,分别处理不同的Service,分离管理逻辑与应用逻辑的队列,保证互不干扰;

Responder单线程的模式,是否高并发应用的瓶颈所在?

是否可以分离Read/Write请求占用的队列,以及处理的handler,从而使得读写性能能够更加平衡?

针对读写应用的特点,在RpcServer层次内对应用进行分级,建立不同优先级的CallQueue,按照Hadoop-FairScheduler的模式,然后配置中心调度(类似OMega或者Spallow轻量化调度方案),保证实时应用的低延迟和非实时应用的高吞吐。优先级更好的Call会优先被调度给Handler,而非实时应用可以实现多个Call的合并操作,从而提高吞吐。

3)Protobuf内置编码与传统压缩技术是否可以配合使用?

使用tcpdump获取了一段HMaster得到的RegionServer上报来的信息:

深入分析HBase RPC(Protobuf)实现机制

以上的信息几乎是明文出现在tcp-ip连接中,因此,是否在Protobuf-RPC数据格式采取一定的压缩策略,会给scan、multiGet等数据交互较为密集的应用提供一种优化的思路。

参考文献:

[1] HBase Rpc Protocols: ?http://blog.zahoor.in/2012/08/protocol-buffers-in-hbase/

[2] HBase project 0.95.1
本系列文章属于Binos_ICT在Binospace个人技术博客原创,原文链接为http://www.binospace.com/index.php/in-depth-analysis-hbase-rpc-0-95-version-implementation-mechanism/,未经允许,不得转载。

From Binospace, post 深入分析HBase RPC(Protobuf)实现机制

文章的脚注信息由WordPress的wp-posturl插件自动生成


Copyright © 2008
This feed is for personal, non-commercial use only.
The use of this feed on other websites breaches copyright. If this content is not in your news reader, it makes the page you are viewing an infringement of the copyright. (Digital Fingerprint:
)
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

无法连接到RPC服务器导致无法进入桌面的解决方法 无法连接到RPC服务器导致无法进入桌面的解决方法 Feb 18, 2024 am 10:34 AM

RPC服务器不可用进不了桌面怎么办近年来,计算机和互联网已经深入到我们的生活中的各个角落。作为一种集中计算和资源共享的技术,远程过程调用(RPC)在网络通信中起着至关重要的作用。然而,有时我们可能会遇到RPC服务器不可用的情况,导致无法进入桌面。本文将介绍一些可能导致此问题的原因,并提供解决方案。首先,我们需要了解RPC服务器不可用的原因。RPC服务器是一种

华为手机如何实现双微信登录? 华为手机如何实现双微信登录? Mar 24, 2024 am 11:27 AM

华为手机如何实现双微信登录?随着社交媒体的兴起,微信已经成为人们日常生活中不可或缺的沟通工具之一。然而,许多人可能会遇到一个问题:在同一部手机上同时登录多个微信账号。对于华为手机用户来说,实现双微信登录并不困难,本文将介绍华为手机如何实现双微信登录的方法。首先,华为手机自带的EMUI系统提供了一个很便利的功能——应用双开。通过应用双开功能,用户可以在手机上同

PHP编程指南:实现斐波那契数列的方法 PHP编程指南:实现斐波那契数列的方法 Mar 20, 2024 pm 04:54 PM

编程语言PHP是一种用于Web开发的强大工具,能够支持多种不同的编程逻辑和算法。其中,实现斐波那契数列是一个常见且经典的编程问题。在这篇文章中,将介绍如何使用PHP编程语言来实现斐波那契数列的方法,并附上具体的代码示例。斐波那契数列是一个数学上的序列,其定义如下:数列的第一个和第二个元素为1,从第三个元素开始,每个元素的值等于前两个元素的和。数列的前几个元

如何在华为手机上实现微信分身功能 如何在华为手机上实现微信分身功能 Mar 24, 2024 pm 06:03 PM

如何在华为手机上实现微信分身功能随着社交软件的普及和人们对隐私安全的日益重视,微信分身功能逐渐成为人们关注的焦点。微信分身功能可以帮助用户在同一台手机上同时登录多个微信账号,方便管理和使用。在华为手机上实现微信分身功能并不困难,只需要按照以下步骤操作即可。第一步:确保手机系统版本和微信版本符合要求首先,确保你的华为手机系统版本已更新到最新版本,以及微信App

掌握Golang如何实现游戏开发的可能性 掌握Golang如何实现游戏开发的可能性 Mar 16, 2024 pm 12:57 PM

在当今的软件开发领域中,Golang(Go语言)作为一种高效、简洁、并发性强的编程语言,越来越受到开发者的青睐。其丰富的标准库和高效的并发特性使它成为游戏开发领域的一个备受关注的选择。本文将探讨如何利用Golang来实现游戏开发,并通过具体的代码示例来展示其强大的可能性。1.Golang在游戏开发中的优势作为一种静态类型语言,Golang在构建大型游戏系统

PHP游戏需求实现指南 PHP游戏需求实现指南 Mar 11, 2024 am 08:45 AM

PHP游戏需求实现指南随着互联网的普及和发展,网页游戏的市场也越来越火爆。许多开发者希望利用PHP语言来开发自己的网页游戏,而实现游戏需求是其中一个关键步骤。本文将介绍如何利用PHP语言来实现常见的游戏需求,并提供具体的代码示例。1.创建游戏角色在网页游戏中,游戏角色是非常重要的元素。我们需要定义游戏角色的属性,比如姓名、等级、经验值等,并提供方法来操作这些

如何在Golang中实现精确除法运算 如何在Golang中实现精确除法运算 Feb 20, 2024 pm 10:51 PM

在Golang中实现精确除法运算是一个常见的需求,特别是在涉及金融计算或其它需要高精度计算的场景中。Golang的内置的除法运算符“/”是针对浮点数计算的,并且有时会出现精度丢失的问题。为了解决这个问题,我们可以借助第三方库或自定义函数来实现精确除法运算。一种常见的方法是使用math/big包中的Rat类型,它提供了分数的表示形式,可以用来实现精确的除法运算

Go语言RPC框架盘点:五大热门选择一览 Go语言RPC框架盘点:五大热门选择一览 Feb 27, 2024 pm 01:03 PM

随着互联网技术的发展,分布式系统的应用越来越广泛,而远程过程调用(RPC)作为分布式系统中的重要通信方式,也受到了越来越多的关注和应用。在众多的RPC框架中,Go语言作为一种快速高效的编程语言,也拥有着丰富的RPC框架选择。本文将针对Go语言RPC框架进行盘点,介绍五大热门选择,并给出具体的代码示例,帮助读者更好地了解和选择适合自己项目的RPC框架。1.g

See all articles