Hbase Java Client简介

概述以及架构

我们在使用hbase的时候,数据操作都是和regionserver直接通信操作,hbase的Java客户端将这些操作都封装在HTable类中,对外我们使用的所有操作都是直接使用HTable的api来直接操作,HTable的基本操作如下:

get、get list、put、put list、delete、delete list、append、Increment、checkAnd***、scan 。

hbase client架构图如下:

虚线中的部分是线程安全的,在整个jvm client中可以维持一份来供多线程使用,避免资源的重载,资源重建等耗时操纵。

HTable

Htable是对外的数据操作接口,提供了hbase基本所有的数据操作方法, htable中提供了buffer的功能(BufferedMutator),当buffer达到一定的size或者num后,会自动后台线程flush到相应的regionserver。

目前这个buffer只针对put(put list)操作并且需要关闭自动提交,可以异步提交put请求并并flush,其它操作都是同步完成,有些单个的请求是直接同步发送rpc请求,批量的操作涉及到多个regionserver通信的操作,会分组做成runnable,提交到thread pool并行执行,待所有执行完成后返回。

Htable中目前看除了带buffer的put操作,其它的操作其实还都是线程安全的,因为其它操作基本上没有太多共用的属性,而且操作大头其实都是聚集在connection(regionlocation cache、rpc socket)中,而connection中的操作都是线程安全的。

htable的构造方法如下:

需要connection和相应的配置,可以自定义executorService,也可以直接从connection.getTable(TableName)方法获得,创建这些table其实是没有太多开销的,底层的connection共用,如果executorService为null则共用connection中的executorService,建议这样。

ps:在1.0以前的HTable中会有用configuration 和 tableName作为构造参数来初始化HTable的方法,这样其实会在初始化的时候重新create一个connection对象,connection相关的resource也会重新创建,关闭的时候一并关闭了,1.0之后这些方法都打上过时标识了,以后不建议使用。

Connection

整个client中最重要的一部分,可以理解为和整个hbase集群的连接,管理着两部分共用的东西,当然这两部分的初始化也是最耗时间的:

1、region cache,每个表的region以及region handle的数据范围,所在的regionserver等信息,这部分数据是在用到时候会更具row去meta表中查到相对应的信息(每次查询是一张表一张表的数据缓存的),然后就一直缓存起来,直到使用这个cache出现RegionNotOnline、moved、notexsit等异常从regionserver反馈回来的时候,再更新cache,每个region都有一个唯一的id,已开这个id去定位唯一的region的,这个id在split、merger等操作后都是会改变的,所以不会出现在split和merger操作后的歧义。

2、连接到各个regionserver的通信socket,具体在使用上的体现就是RpcClientImpl,每个regionserver一个socket连接 。

这两部分资源在使用时候都是线程安全的,所以在整个client的jvm中维护一个connection即可,也恰恰是这两部分的cache/连接在整个数据通信中是最耗时的两部分操作。

关于Connection的使用以及初始化,在1.0版本以前,所有的Connection由ConnectionManage来管理,保存在一个静态Map中,可以通过全局的get方法得到,1.0以后这些方法还存在,但是都已加上过时标志,建议用户通过ConnectionFactory来创建链接并管理、使用、销毁。

所以在并发的环境下建议的使用代码就是:

Connection connection = ConnectionFactory.createConnection(config); //创建后的connection需要使用者保存维护,并在程序最后结束的时候destroy掉,比如jvm stop hook中

//具体的使用如下

Table table = connection.getTable(TableName.valueOf("table1"));

table.close();

由于connection是公用的,所以在create、destroy HTable的时候其实开销并不大,从目前1.0的api以及api过时标注来看,建议的也是使用这自己初始化connection并管理,其余的HTable从其上面衍生出来来使用。

ExecutorService

其实就是java中的ExecutorService,目前主要用于批量(flush put buffer也算是批量)执行的时候,因为批量执行时,其中的请求会发送到多个regionserver上,所以使用线程池的方式来并发执行这些rpc请求。

Hbase rpc interface

hbase client在使用的过程中数据的操作都是直接跟regionserver来交互的,hbase rpc接口(包括regionserver)目前都是使用protobuf来定义interface和VO数据,这样做的目的是为了做多语言的兼容,目前regionserver的rpc接口如下(省略了bulkload和coprocess的接口):

service ClientService {

//单个的get接口

rpc Get(GetRequest)

returns(GetResponse);

//批量处理基本的操作(get/put/delete/append/incerament都支持),这个和Multi的区别是,这个支持整个操作原子性,所以类似于checkand***/单个的append、increment的都会走到这个

rpc Mutate(MutateRequest)

returns(MutateResponse);

//scan接口,这个接口在调用的时候第一次是打开一个scanner并产生一个scanner id,后续再根据这个scanner的squence id去一批批的取数据。

rpc Scan(ScanRequest)

returns(ScanResponse);

//如上面介绍,这个不支持原子操作的,hbase的原子操作靠的是mvcc来实现的

rpc Multi(MultiRequest)

returns(MultiResponse);

}

PS:最初的hbase版本沿用了hadoop的writable序列化接口,在0.96的rpc系统中写了一套兼容writable和pb的rpc,在0.98开始全面移除了对于writable的兼容,这种方式对于向后兼容以及跨语言是个很好的支持。

Hbase RPC底层

Hbase rpc底层通信类似于hadoop的一套rpc,异步rpc client,其实说白了就是一套,只不过是两份代码。

序列化目前全部采用的是pb来做的序列化,没有了以前的hadoop中的writable那一套,其底层的socket通信采用的是socket的简单同步通信方式,在这个socket之上做了sender 和 receiver(其实就是两个线程了),来达到异步的效果,简单的流程就是:

1、client 发送call请求(每个call都会被分配一个squenceId);

2、sender接收到缓存起来,然后client在call上wait(timeoutInMilli),等待被唤醒,在等待超时后会抛出异常,可以认为请求等待超时,这一步其实可以做成异步的形式,不wait,只是发送请求。

3、sender中的主线程不停的发送自己缓存起来的call,发送的时候会在底层的socket上加锁,所以这一步是线程原子操作;

4、receiver不停的接收服务端的返回,去取response然后根据call id找到相应的call并唤醒相应的call ;

如上面的第2步所示,底层的rpc其实是留了异步的接口,但是hbase上层在调用的时候才用了wait来达到同步调用的效果。

Hbase操作分类

put、put list,这两个操作在htable关闭自动刷新的时候,数据会先缓存到buffer中,然后buffer溢出后在批量flush,使用executorservice的线程pool来并行写数据,其最终调用的是regionserver的Multi(MultiRequest)接口。

get、delete这两个操作会直接发送到相应的regionserver,所有的操作都是在调用线程中完成,调用底层的rpc发送接口,get调用Get(GetRequest),delete调用Multi(MultiRequest)。

get list、del list最终都会转换为hbase的batch方法,底层再调用Multi(MultiRequest)接口,只不过和put处理流程一直,因为可能会涉及到多个regionserver,所以会将所有的请求按照regionserver分组,然后并发处理(使用executorservice中的thread pool)每个regionserver的请求,只不过batch是同步调用的,需要等待所有的调用over后才会主方法返回。

Append、increament以及一些CAS操作也是在直接发送到相应的rs,所有的操作都是在调用线程中完成,最终调用底层的Mutate(MutateRequest)接口。

Scan是一个比较特殊的操作,scan的数据是分批量从regionserver取回的,第一次调用Scan(ScanRequest)方法的时候(注意scan操作会将start-end分到相应的region上,从第一个region开始遍历,批量取回数据),会在regionserver中打开一个scanner生成唯一的scannerid并记录读取offset等信息,下次调用的时候会从上次的offset开始取数据,知道结束,然后客户端会飘到下一个region上。整个scan是一个客户端和server配合完成的过程,每次请求会有scannerid和请求的squenceid,服务端会根据这些判断是请求是否合法,是否是网络抖动引起的重复请求等行为,而且在regionserver上会对每个scanner做超时检测,超时的时候移除相应的scanner。

关于batch操作时候的异常处理

在batch处理 (底层调用Multi(MultiRequest)方法) 的时候,这时候和regionserver通信时允许部分操作失败的,在收到失败异常后会对异常进行分类,一些逻辑如下:

1、RegionTooBusyException、RegionTooBusyException的话,不处理

2、RegionMovedException 会更新cache ,因为这个异常会带回新的region的位置rs信息

其它异常的会,会先判断一些现在的cache对应的还是不是我之前用的那个region对应关系了,是的话再清理, 因为有可能我用的过程中已经被别人更新了。

3、DoNotRetryIOException时候才不会再重试了 ,对应的操作会被移除并不被重试。

这一块其实应该把异常处理能留出一个用户自定义的接口,有些环境中其实是需要快速失败的。

在重试一定的次数(hbase.client.retries.number配置,默认是31)或者一定的时间(hbase.rpc.timeout配置,默认是60s)后,则失败。

关于async hbase

Async hbase是OpenTSDB 项目中,作者重写的一个hbase客户端

今年的HBaseCon上作者的一个演讲ppt

简单读了下代码,几点总结如下:

1、线程安全,一个HbaseClient使用整个jvm中。

2、完全异步提交数据,客户端缓存数据、另外线程刷新数据,失败异常等使用callback的形式回调。

3、完全没有用hbase client中的代码,rpc的通信头构造都是自己构造的,数据刷新具体逻辑没细看,感觉掐掉了很多hbase原生client的重试、异常检测等一系列的fault-tolerant功能, 为了性能。

4、掐掉了原生hbase的一些操作,目前看只支持put、del和相应的cas,scan,get这些操作。

5、底层通信使用的是netty的nio style client,完全的异步行为。hbase(hadoop)的rpc client是一个模拟的异步socket, 调用send的时候,其实是有个sender的线程把你的call缓存了,这个线程的工作就是一直从queue中取出call写socket,receiver线程,一直从inputStream读数据,读到response后解码并,更细call为complement状态,同步socket一种类异步的封装。

1.0的一些新特性

region replicas

region副本,每个region会在多个regionserver上打开,但是只有一个主region接收写请求,其它的都是readonly, 这个region可以使用更新到hdfs上的文件数据,但是memstore中的数据会延后,对于大量读但对一致性要求不高的场景,不过这个目前还是个实验性质的feature。

动态conf

就是动态修改并加载配置,不需要重启集群。

hbase java client 简介_hbase Java client(Release 1.0)相关推荐

  1. 认识 Java(Java 发展简介)+Java语言特点

    认识 Java(Java 发展简介)+Java语言特点 目录: 一.Java 的具体内容. 二.Java 编程语言介绍. 三.SUN 公司的由来. 四.Java 的开发形式. 五.Java的开发技术 ...

  2. ibm java_IBM i 上Java 虚拟机简介

    Abstract IBM i 上Java 虚拟机简介 Body Java在IT业界有多流行?google上搜索一下java, 结果一目了然(今天早上我搜索到的记录数是840000000条).Java之 ...

  3. OpenCV Java开发简介

    OpenCV Java开发简介 OpenCV Java开发简介 我们将在本指南中做什么 获得适当的OpenCV 下载 构建 Java示例与Ant Java和Scala的SBT项目 运行SBT样本 Op ...

  4. JAVA NIO 简介 (netty源码死磕1.1)

    [基础篇]netty 源码死磕1.1:  JAVA NIO简介 1. JAVA NIO简介 Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO.由于之前老的I/O类库是阻塞I/ ...

  5. 阿里云大学 Java编程入门(一)Java语言简介

    Java语言简介 一.Java语言简介 1.1 认识Java(Java发展简介) 1.2 Java语言特点 1.3 Java可移植性 本系列内容为阿里云大学 java学习路线里的内容 阿里云大学 ja ...

  6. android java框架_【阿里P8大牛教你Android入门之路(java篇)】——Java集合框架(系列篇1)...

    一.前言 本部分内容主要包含以下: Java集合 Java反射 Java注解 Java反射 Java IO 其他面试点 以上内容都是Java中的基础知识,对于Java的学习很有帮助.其中集合.反射.I ...

  7. 内含JAVA简单概括和JAVA所需安装的软件和详细教程,想学习JAVA无从下手,这篇文章带你迈出第一步

    本文大致概括了JAVA编程语言的简史和特点,主要介绍了JAVA开发环境安装,涉及JDK,Sublime Text IntelliJ IDEA三个软件的简单介绍,安装和使用,最后编写了第一个JAVA代码 ...

  8. 【2022最新Java面试宝典】—— Java异常面试题(33道含答案)

    目录 一.Java异常架构与异常关键字 1. Java异常简介 2. Java异常架构 1.Throwable 2. Error(错误) 3. Exception(异常) 运行时异常 编译时异常 3. ...

  9. java套接字客户端_使用Java从客户端套接字读取数据(Read data from a client socket in Java)...

    使用Java从客户端套接字读取数据(Read data from a client socket in Java) 我编写了从客户端套接字发送/接收数据的代码. 发送数据步骤已成功完成,但是当我想从套 ...

  10. java server模式 设置_JVM client模式和Server模式的区别

    这里向大家描述一下JVM client模式和Server模式两者的区别和联系,JVM如果不显式指定是-Server模式还是-client模式,JVM能够根据下列原则进行自动判断(适用于Java5版本或 ...

最新文章

  1. eclipse目录出现重复情况 解决
  2. Jena+fuseki安装配置教程
  3. 记录皮尔逊相关系数-相似性比较算法
  4. 小学数学加减法测试软件,小学生数学加减测试题
  5. c语言入门教程文库,C语言入门教程(全集)课件
  6. [转]HTTP/3 未来可期?
  7. 递归函数里面又有2个调用自身的递归函数里面参数变化总结
  8. ViceDinoSpecCtrlDlg.cpp
  9. python有趣的案例_Python有趣的小案例
  10. 在Centos环境下搭建Confluence
  11. 计算机教师职业幸福感,教师的职业幸福感是什么
  12. Java就业培训教程重点部分的笔记
  13. Agisoft Metashape照片转3D模型打印拿宇树狗做个实验
  14. NetApp 数据存储 AFF 和 FAS 系统的磁盘架和存储介质
  15. 安卓开发调用python脚本_android开发调用python脚本
  16. 计算机系统缺什么安装CAD闪退咋办,怎么处理CAD启动后闪退,求大神级人物解决...
  17. word转excel排版不变怎么转?
  18. Matlab机器人的仿真(八):绘制机器人运动轨迹(复现)
  19. SAP UI5 应用开发教程之八十三 - SAP UI5 的自动化测试套件页面的开发步骤介绍试读版
  20. java计算机毕业设计二手车商城源码+mysql数据库+系统+lw文档+部署

热门文章

  1. C语言typedef
  2. MySQL查看binlog是否开启(开启binlog)
  3. python有关数据结构问题
  4. 主题模型LDA理解与应用
  5. Android Service中的android:process=:remote
  6. 基于16QAM调制的OFDM系统仿真实现(MATLAB)
  7. android反调试之父子调试
  8. swift使用cocoapods导入第三方库
  9. Download SQL Server Management Studio (SSMS)下载地址
  10. 在ios中制作3d文字球效果