本文将介绍HBase的客户端连接实现,并说明如何正确管理HBase的连接。

最近在搭建一个HBase的可视化管理平台,搭建完成后发现不管什么查询都很慢,甚至于使用api去listTable都要好几秒。

经过一番排查发现,是每次请求的时候,都去临时创建了一个connection,而创建connection非常耗时导致整体的rt上升。

因此,就深入了解了下如何正确管理HBase的connection,同时,也在优化过程中有些小细节的总结。

本文基于hbase 2.0.0版本的源码,github上3.0版本的源码已经有很大差异了,但是思想还是差不多的

1.HBase-client和HBase是如何连接的?

这个问题实际上在我之前的文章 深入HBase读写 中介绍过。

当HBase-client第一次请求读写的时候,需要三步走:

1)HBase-client从zk中获取保存meta table的位置信息,知道meta table保存在了哪个region server,然后缓存这个位置信息;

2)HBase-client会查询这个保存meta table的特定的region server,查询meta table信息,在table中获取自己想要访问的row key所在的region在哪个region server上。

3)客户端直接访问目标region server,获取对应的row

所以,我们知道hbase-client实际上包含三部分连接:

  • 跟zk连接,获取相关元信息
  • 跟HMaster连接,做相关DDL操作
  • 直接跟各个region server进行连接,进行增删改查

2.HBase客户端连接原理

常规写法是这样的

Connection connection = ConnectionFactory.createConnection(conf);

try {
Table table = connection.getTable(TableName.valueOf("tablename”));
// 插入数据
Put put = new Put(Bytes.toBytes("row"));
put.addColumn(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), Bytes.toBytes("value"));
table.put(put);
// 单行读取
Get get = new Get(Bytes.toBytes("row"));
Result res = table.get(get);
// 删除一行数据
Delete delete = new Delete(Bytes.toBytes("row"));
table.delete(delete);
}catch (IOException e) {
//.....
} finally {
table.close();
connection.close();
}

我们不禁有这样的疑问:

1)HBase没有连接池吗?

2)connection表示的是一个连接吗?

3)connection每个线程都得创建吗?线程安全吗?

4)table每个线程都得创建吗?线程安全吗?

下面一一解答。

首先,Connection是线程安全的,而Table和Admin则不是线程安全的。

因此正确的做法是一个进程(或服务)使用一个Connection对象,而在不同的线程中使用单独的Table和Admin对象。

Connection持有RpcClient,RpcClient管理了一个连接池poolMap

protected final PoolMap<ConnectionId, T> connections;

//….

this.connections = new PoolMap<>(getPoolType(conf), getPoolSize(conf));

通过AbstractRpcClient的getConnection看到,连接T继承RpcConnection,叫做NettyRpcConnection。

这里顺便通过getPoolType和getPoolSize看了下线程池的大小和类型。

在枚举类PoolType中有三种线程池类型Reusable, ThreadLocal, RoundRobin,用户可以用hbase.client.ipc.pool.type指定线程池类型,通过hbase.client.ipc.pool.size指定线程池大小(默认是1)。

3.优化实践

搞清楚上面的原理后,下面就可以开始优化我们的HBase管理平台了。

只需要对每个HBase集群的connection使用Map保存下来,每次请求的时候拿出对应的connection进去相关操作即可。然后需要注意在系统退出的时候关闭所有的connection。

上代码:

public class ConnectionManager {
private Map<String, Connection> connectionMap = new ConcurrentHashMap<>(); public Connection getConnection(String resourceId, Configuration configuration) {
ResourceInfo resourceInfo = ResourceInfoCache.getResourceInfoByCache(resourceId);
if (resourceInfo == null) {
throw new IllegalArgumentException("error resourceid: " + resourceId);
}
String key = getClusterKey(resourceInfo);
if (connectionMap.containsKey(key)) {
return connectionMap.get(key);
}
synchronized (this) {
//DCL检查
if (connectionMap.containsKey(key)) {
return connectionMap.get(key);
}
Connection connection = null;
try {
connection = ConnectionFactory.createConnection(configuration);
} catch (IOException e) {
return null;
}
connectionMap.put(key, connection);
return connection;
}
} @PreDestroy
public void doDestroy() {
for (Map.Entry<String, Connection> entry : connectionMap.entrySet()) {
Connection connection = entry.getValue();
if (connection != null) {
try {
connection.close();
} catch (IOException e) {
//。。。。
}
}
}
}
}

这里有几个注意点:

  • 将ConnectionManager注册为bean,交给spring容器管理生命周期,同时保证单例。
  • 使用@PreDestroy保证应用关闭时,能正确释放所有连接,避免连接泄漏
  • connectionMap使用ConcurrentHashMap保证线程安全
  • DCL检查,避免重复创建同一个connection,浪费资源;并且避免重复创建connection后,无法关闭导致连接泄漏。

在需要查询时,只需要通过getConnection获取已经存在的connection即可。

当然,如果是普通的应用使用HBase-client,一般只需要对一个HBase的集群创建全局唯一的一个Connection即可(一般交给spring容器管理),每次请求的时候,创建对应的Table进行CRUD。

看到这里了,原创不易,点个关注、点个赞吧,你最好看了~

知识碎片重新梳理,构建Java知识图谱:https://github.com/saigu/JavaKnowledgeGraph(历史文章查阅非常方便)

扫码关注我的公众号“阿丸笔记”,第一时间获取最新更新。同时可以免费获取海量Java技术栈电子书、各个大厂面试题。

如何正确管理HBase的连接,从原理到实战的更多相关文章

  1. HBase存储及读写原理介绍

    一.HBase介绍及其特点 HBase是一个开源的非关系型分布式数据库,它参考了谷歌的BigTable建模,实现的编程语言为Java.它是Apache软件基金会的Hadoop项目的一部分,运行于HDF ...

  2. IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

    本文引用了简书作者“骑小猪看流星”技术文章“Cookie.Session.Token那点事儿”的部分内容,感谢原作者. 1.前言 众所周之,IM是个典型的快速数据流交换系统,当今主流IM系统(尤其移动 ...

  3. Hbase的连接池--HTablePool被Deprecated之后

      说明: 最近两天在调研HBase的连接池,有了一些收获,特此记录下来. 本文先将官方文档(http://hbase.apache.org/book.html)9.3.1.1节翻译,方便大家阅读,然 ...

  4. ssh连接的原理

    ssh是linux系统中的一个远程连接工具,也是一种网络协议,通过各种加密算法达到安全连接的效果.若能使用ssh连接到另外一台机器上,我们就可以认为是安全的.本节主要介绍的是ssh连接的原理以及ssh ...

  5. 管理IPv6网络连接

    以下操作建立在Linux功能-管理IPv4网络连接之上,请先完成该部分操作后进行以下测试. 1. 修改 net1,配置 IPv6 地址为 2001:X/64 ,网关为 2001:254 [root@d ...

  6. 解决SQL Server管理器无法连接远程数据库Error: 1326错误

    解决SQL Server管理器无法连接远程数据库Error: 1326错误 我们在在使用SQL Server时都会遇到使用SQL Server Management Studio无法连接远程数据库实例 ...

  7. 全易通人事考勤工资验厂管理系统软件创建连接SQL2000数据库的操作方法和说明

    全易通人事考勤工资验厂管理系统软件创建连接SQL2000数据库的操作方法和说明.全易通人事考勤工资验厂管理系统软件,有2种数据库,一个是ACCESS,另一个是SQL.不过由于ACCESS数据库比较小, ...

  8. HTTP协议学习笔记---HTTP持久连接和如何正确地关闭HTTP连接

    一,持久连接 什么是持久连接?对于HTTP协议而言,它是基于请求响应模型,Client向Server发请求时,先建立一条HTTP连接,Server给Client响应数据后,连接关闭. 当Client发 ...

  9. Foxpro数据库连接错误解决方法--【VFP DBF文件不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器】

    直接访问vfp dbf文件时报错: 错误描述: 'd:\vfpData\test.dbf'不是一个有效的路径. 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器. 解决办法:Data Sour ...

随机推荐

  1. AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth

    title: "AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth" date: 2020-03-24T23:27:45+08:00 ...

  2. MySQL笔记(6)-- SQL更新语句日志系统流程

    一.背景 在上一篇[MySQL笔记(5)-- SQL执行流程,MySQL体系结构]中讲述了select查询语句在MySQL体系中的运行流程,从连接器开始,到分析器.优化器.执行器等,最后到达存储引擎. ...

  3. input标签的accept属性、JQuery绑定keyDown事件

    一. input标签的accept属性 当我们上传文件或者注册上传头像时,我们可以一般都是使用: <input type="file" id="my_file&qu ...

  4. [币严BIZZAN区块链]Java生成ETH钱包助记词、私钥、地址

    本文主要介绍在Java工程中如何生成ETH钱包的助记词.私钥.地址. 一.在之前创建的spring boot 项目中的 pom.xml文件中加入需要的依赖 <dependency> < ...

  5. java获取近几天的日期

    最近在写接口的时候老遇见从mysql中获取近几天数据的需求,获取日期这块不是很熟,网上看了很多但是代码量都太大,还是问了下别人,写了三行代码就解决了,不多说 贴代码了 下面是我获取近十天,每天的日期: ...

  6. Django HttpResponse

    HttpResponse 概述:给浏览器返回数据 HttpRequest对象是由django创建的,HttpResponse对象由程序员创建 用法 1:不调用模板,直接返回数据. 例: def get ...

  7. C 2012年笔试题

    1指出程序段中的错误:分析错误的原因,并进行修改 1.1函数 swap 将两个字符串(字符数组作实参,长度不超过 100)的内容进行交换 void swap(char *pa,char *pb) { ...

  8. FastAI 简介

    Fastai简介 在深度学习领域,最受学生欢迎的MOOC课程平台有三个:Fast.ai.deeplearning.ai /Coursera和Udacity.Fastai作为其中之一,是一个课程平台,一 ...

  9. 干货 | NLP算法岗大厂面试经验与路线图分享

    最近有好多小伙伴要面经(还有个要买简历的是什么鬼),然鹅真的没有整理面经呀,真的木有时间(。 ́︿ ̀。).不过话说回来,面经有多大用呢?最起码对于NLP岗位的面试来说,作者发现根本不是面经中说的样子 ...

  10. 模块 re_正则

    模块re_正则 讲正题之前我们先来看一个例子:https://reg.jd.com/reg/person?ReturnUrl=https%3A//www.jd.com/ 这是京东的注册页面,打开页面我 ...