先澄清一些本文中术语的涵意
客户端 – 指的是HBase client API.提供了从用户程序连接到HBase后台服务器即Master server及Region server的功能
服务端 – 即指的是HBase的Master server 及 Region server
用户端 – 指用户程序.即对HBase client API的调用方.
本篇的主要目的是说明RPC的客户端实现.解决客户端RPC的最后两个问题
1) 传输,并发及会话控制
2) 其它的保障,如出错,重试等.
首先是RPC传输,并发.及会话
前一篇基础,已经说明HBase client可以得到HMasterInterface 和HRegionInterface的接口实例.具体参看org.apache.hadoop.hbase.client.HConnectionManager.TableServers的两个方法getMaster()和getHRegionConnection(). 从这点说,HBase的RPC与RMI是相似的,即通本地的桩(stub)对象,来传输调用,但对用户来说,这是透明的.
这个实现主要分两大步骤
- 生成接口的实例.这是通过代理类来实现的.
- 方法调用转化为序列化的socket传输.代理类将方法,参数序列化后,用socket传给服务端
第一步,这两个接口的实例,是如何实例化出来?
毫无疑问的是这两个实例是桩(stub)或称为代理,桩的创建是从org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy()这个静态方法中得到的.
下面就详细的说明一下getProxy() ,它的核心是利用的java反射中的动态代理框架.调用java.lang.reflect.Proxy的静态方法newProxyInstance,它需要三个参数:
1)ClassLoader,
2)要实现的接口类(可以有多个),例如HRegionInterface,
3)最后是函数调用代理类java..lang.reflect.InvocationHandler的实例.
也就是说Proxy.newProxyInstantce的功能是将产生一个Object,这个Object实现了指定的接口,其实就是将接口与InvocationHandler的实例绑定了. 对接口中方法的调用将被转发到InvocationHandler实例上.getProxy()将生成的对象转化成VersionProtocol对象然后返回.然后再根据外部的调用将VersionProtocol转化为具体的HRegionInterface或HMasterInterface
在这步,InvocationHandler是由HBaseRPC的内部类Invoker实现的.所有的RPC调用就落实到了它的invoke方法上.invoke又利用org.apache.hadoop.hbase.HBaseClient来完成调用的传输.
第二步中,主要是
1) 序列化.
2) Socket传输.
序列化在第一篇中,已谈到了一点,这里讲一下具体的流程
1) 调用的方法和参数被封装成Invocation(HBaseRPC内部类)对象. Invocation本身就是一个Writable对象.函数名被传化成一个编码code.可以看到Invocation内部有两个表,即方法名到一个字节值的双向的映射.首先方法名被排序了,然后它们对应的字节code从0依次增一.重载的方法编码相同,但可以根据参数不同来区分的.参数依次被序列化成HbaseObjectWritable对象.这个通过个Invocation对象,调用就可以输出成数据流或从数据流中输入.
2)这个协议的下层封装是由HBaseClient的内部类Call实现的,Call装入前述的Invocation对象,从当前的连接类HBaseClient取得一个id,这是一个自增量,然后将这个id及流的长度及Invocation通过socket连接发送出去.并同步等待(Call.Wait())返回结果.Call对象实例被放入了另一个内部类Connection的一个表calls中,是id(integer)到Call实例的映射.如果Call实例的完成标志被置,则说明结果被保存在了它的value字段中.后续反序列化的就不详述了.

以后就Socket传输的机制工作了.
Connection主要负责传输. 主要成员socket(java.net.Socket)是一条到HBase Server连接. 在这条连接上, Connection是传输调用并接收结果.它也支持并发.前面提到的calls表存放了所有正在进行传输的Call.每个Call都是从一特定的调用者线程中发起.但数据接收却不在调用者线程.
Connection本身是java.lang.Thread的子类,在它本身的线程会在socket连接建立时启动,功能是循环检查当前有没有调用Call存在,如果有就试着从socket上读取结果.并分析出结果是对应到哪个(查calls表)Call,将结果放入Call,并设置Call的完成标志,通知(call.notify())调用者线程.
最后介绍客户端的RPC容错和重试机制.
从用户端看到API并不是直接的HRegionInterface或HMasterInterface,而是HTable之类已经包装的比较高级的API.
HTable这层的功能封装是较复杂的,因为这一层的操作会分配到不同HBase服务器上,比如说,从上层看只是对一个表的查询,但在HTable这层被分解成为了对不同HRegionInterface的调用.因为一个表是有多个Region的,而不同的Region被分配到了不同的Region Server上了,而一个HRegionInterface又代表了一个Region Server.另外,为了获得Region在服务器上的分布,还要扫描Root表和Meta表等等.
本文的重点在是在HTable的业务逻辑与RPC底层机制之间部分—容错机制.
HTable 所有引起RPC调用的方法,一般都会调用到HConnectionManager.TableServers的getRegionServerWithRetries()这个方法,
以简单的HTable.delete(Delete)这个函数为例,你可以看到一个对HRegionInterface.delete的调用被封装成了一个org.apache.hadoop.hbase.client.ServerCallable对象.这个对象然后被作为参数传入了getRegionServerWithRetires方法调用.
在这个方法内部,这个ServerCallable对象被调用到,成功了就返回,否则尝试调用多次,默认10次.每次调用时的间隔还逐渐拉长.其中还将出错抛出的异常记到一个列表中,以便最终失败的时候分析原因.
考虑以下情况,当一个Region正被迁移,最初时Delete中的row key对象可能由Region Server 1来管理,但当调用发生后客户端收到了出错,因为此时这个row key从属的Region由Region Server 2来服务了.在这种重试机制下,都会经过两个流程
1) 调用ServerCallable.instantiateServer(). 这步会重置,这个row key所属的location及对应的Region server.这样就可以获得region server 2了.
2) 调用ServerCallable.call().重新发起调用.
这个机制也兼顾了一些特别情况,比如客户端可以收到一条称为DoNotRetryIOException的异常,这样客户端就不会再试了.举例来说,当执行Scan操作时,当Region迁移时,服务端会要求客户端在其它Region server上重启Scan,而不要继续.
分享到:
相关推荐
总的来说,HBase的源码分析涉及到客户端与服务器的交互、RPC通信机制、数据存储流程以及系统架构等多个层面。理解这些核心机制对于优化HBase性能、排查问题以及进行二次开发都至关重要。通过对HBase源码的深入学习,...
4. RPC机制:理解HBase如何通过HBaseRpcController和RpcServer实现客户端与服务器之间的通信。 5. 并发控制:学习RegionSplitPolicy、RegionSplitter等类,理解HBase如何处理并发请求和Region分裂。 6. 客户端API:...
### HBase源码分析 #### 一、HBase性能测试要点与分析 ##### 1.1 测试环境 - **硬件配置**: - 客户端:1台 - RegionServer:5台 - Master:1台 - ZooKeeper:3台 - **软件配置**: - CPU:每台服务器配备8...
HBase 0.94.4的源码分析有助于我们深入了解其内部机制,从而更好地进行系统设计和优化。无论是对于开发者还是管理员,掌握HBase的核心原理都将极大地提升在大数据领域的实践能力。通过不断学习和实践,我们可以更好...
源码分析有助于提升对空间和时间复杂度的理解。 8. **Test-HBase**: 测试模块,包含了HBase的单元测试和集成测试,这对于理解HBase的正确性验证和测试策略非常重要。 9. **HBase Hadoop Compat**: 类似于HBase ...
源码分析是理解HbaseClient工作原理的关键。通过阅读源码,我们可以发现HbaseClient在执行操作时,会先将请求序列化成protobuf消息,然后通过HBase的RPC协议发送到RegionServer。RegionServer接收到请求后,解析并...
《深入解析Hadoop之HBase 0.99.2源码分析》 在当今的信息化社会,大数据处理已经成为企业核心竞争力的关键要素。Hadoop作为开源大数据处理框架的领头羊,其生态中的HBase更是备受关注。HBase是基于Google Bigtable...
客户端通过 RPC(远程过程调用)机制与 HMaster 和 HRegionServer 进行通信。 2. **HMaster**:HMaster 负责整个 HBase 集群的管理和协调工作,包括管理 HRegionServer、处理负载均衡、管理元数据等。HMaster 并不...
通过阅读源码,可以了解其内部的Region分配策略、数据存储格式、RPC通信机制等细节,这对于理解和优化HBase系统非常有价值。 9. **扩展性** HBase支持多种插件和扩展,如Coprocessor机制,允许用户在RegionServer...
6. **HDFS源码分析**:研究HDFS如何实现高效的数据存储和访问机制,这对于理解大数据处理中的数据管理至关重要。 7. **Google ProtoBuf源代码分析**:了解Google的ProtoBuf是如何实现高效的序列化和反序列化,有助于...
10-hdfs下载数据源码分析-getFileSystem2.avi 第三天 mapreduce的原理和编程 01-hdfs源码跟踪之打开输入流.avi 02-hdfs源码跟踪之打开输入流总结.avi 03-mapreduce介绍及wordcount.avi 04-wordcount的编写和...
9. **源码分析**:通过查看源码,我们可以学习Thrift的内部实现,包括编译器生成代码的模板、各种协议的实现细节以及服务器和客户端的运行机制。 10. **应用场景**:Thrift广泛应用于分布式系统,如大数据处理、...
HBase是一个基于列的分布式数据库,提供快速随机访问和大规模数据分析。HDFS是一个高吞吐量的分布式文件系统,是GFS的开源实现。 在Hadoop中HDFS源代码分析方面,主要功能组件、体系结构、NameNode和DataNode的实现...
标题“HBaseSmallScanBug”涉及的是一个特定的HBase使用问题,主要集中在小型扫描(small scans)上,这个问题在HBase的特定版本hbase-0.98.3-hadoop2上被发现。HBase是一款分布式、面向列的NoSQL数据库,常用于大...
PDFBox 是一套开放源码的Java工具,用于处理PDF文档。 #### 计算机视觉 - **JavaCV**: 框架。JavaCV 是一个包装了OpenCV、FFmpeg等多媒体库的Java库。 #### 工具集合 - **Guava**: 工具。Guava 是Google的核心库,...