简简单单用一下 Hbase
一、Hbase 介绍
https://hbase.apache.org/book.html#_preface
https://blogs.apache.org/hbase/
https://research.google.com/archive/bigtable.html
什么是Hbase?
hadoop 数据库:分布式、可伸缩、大数据存储。
二、Hbase client
最开始引入 hbase-client,服务有使用【google/protobuf/wrappers.proto】,有很多包冲突,所以直接使用了 habase-shade-client:
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-shaded-client</artifactId>
<version>${hbase.shade.client.version}</version>
</dependency>
三、Hbase 配置
hbase.zookeeper.quorum
zookeeper server 地址,逗号分割。本地模式和伪集群模式下,默认为 127.0.0.1hbase.zookeeper.property.clientPort
zookeeper server 端口,默认 2181hbase.client.retries.number
hbase client 所有操作的重试上限,默认 15。client 首先等待 hbase.client.pause 执行第一次重试,之后每隔 10s 再次执行。hbase.rpc.timeout
hbase client 一次 rpc 操作的超时时间(超时基于ping检查),默认60000ms,触发则抛出 TimeoutException 异常。hbase.client.operation.timeout
hbase client 一次操作的总的时间限制, 默认 1200000ms,触发则直接抛出 SocketTimeoutException 异常。- 示例:
@Configuration
public class HBaseConfig {
@Value("${hbase.zookeeper.quorum}")
private String hbaseZkQuorum;
@Value("${hbase.zookeeper.property.clientPort:2181}")
private String hbaseZkPort;
@Value("${hbase.client.retries.number:2}")
private String hbaseClientRetry;
@Value("${hbase.rpc.timeout:2000}")
private String hbaseRpcTimeout;
@Value("${hbase.client.operation.timeout:3000}")
private String hbaseClientOperationTimeout;
@Bean
public Connection hbaseConnection() throws IOException {
org.apache.hadoop.conf.Configuration hbaseConfig = HBaseConfiguration.create();
hbaseConfig.set("hbase.zookeeper.property.clientPort", hbaseZkPort);
hbaseConfig.set("hbase.zookeeper.quorum", hbaseZkQuorum);
hbaseConfig.set("hbase.client.retries.number", hbaseClientRetry);
hbaseConfig.set("hbase.client.operation.timeout", hbaseClientOperationTimeout);
hbaseConfig.set("hbase.rpc.timeout", hbaseRpcTimeout);
return ConnectionFactory.createConnection(hbaseConfig);
}
@Bean
public HbaseSimpleTemplate hbaseSimpleTemplate(@Qualifier("hbaseConnection") Connection hbaseConnection) {
return new HbaseSimpleTemplate(hbaseConnection);
}
}
四、关于 Connection
1、Connection 是什么?
集群 connection 封装了底层和实际 hbase server 及 zookeeper 的连接。由 ConnectionFactory 创建并由发起端维护其整个生命周期。
承载了服务发现(hbase master 及 region server)及本地缓存维护(存储及更新)逻辑。所以基于此链接实例化而来的 Table 和 Admin 共享此信息。
2、Connection 怎么使用?
Connection 创建是一个很重的操作。
Connection 实现是 thread-safe 的。
所以通常的操作时,一次创建,到处使用。
这里我们通过 @Bean 注解,将 connection 实例交由 spring 管理,维护其从创建,使用到销毁的整个生命周期。
三、HbaseSimpleTemplate
Hbase Connection 数据操作封装:
row->column->all cells
row->column->cells
rows->column->cells
public class HbaseSimpleTemplate {
private Connection hbaseConnection;
public HbaseSimpleTemplate(Connection hbaseConnection) {
this.hbaseConnection = hbaseConnection;
}
/**
* 结果映射map
*
* @param result
* @return
*/
private Map<String, String> resultToMap(Result result) {
if (result == null || result.isEmpty()) {
return new HashMap<>();
}
return result.listCells().stream().collect(
Collectors.toMap(cell -> Bytes.toString(CellUtil.cloneQualifier(cell)), cell -> Bytes.toString(CellUtil.cloneValue(cell))));
}
/**
* 查询
* @param tableName
* @param rowName
* @param familyName
* @return
* @throws IOException
*/
public Map<String, String> get(String tableName, String rowName, String familyName) throws IOException {
Map<String, Map<String, String>> resultMap = get(tableName, Collections.singletonList(rowName), familyName, null);
return resultMap.values().stream().findFirst().orElse(new HashMap<>());
}
/**
*
* @param tableName
* @param rowName
* @param familyName
* @param qualifiers
* @return
* @throws IOException
*/
public Map<String, String> get(String tableName, String rowName, String familyName, List<String> qualifiers) throws IOException {
Map<String, Map<String, String>> resultMap = get(tableName, Collections.singletonList(rowName), familyName, qualifiers);
return resultMap.values().stream().findFirst().orElse(new HashMap<>());
}
/**
* 批量查询
*
* @param tableName
* @param rowNames
* @param familyName
* @return
* @throws IOException
*/
public Map<String, Map<String, String>> get(String tableName, List<String> rowNames, String familyName, List<String> qualifiers) throws IOException {
Map<String, Map<String, String>> resultMap = new HashMap<>();
List<Get> gets = new ArrayList<>();
rowNames.forEach(rowName -> {
Get get = new Get(rowName.getBytes());
if (CollectionUtils.isNotEmpty(qualifiers)) {
qualifiers.forEach(qualifier -> get.addColumn(familyName.getBytes(), qualifier.getBytes()));
} else {
get.addFamily(familyName.getBytes());
}
gets.add(get);
});
Arrays.stream(hbaseConnection.getTable(TableName.valueOf(tableName)).get(gets))
.forEach(result -> {
Map<String, String> kvMap = resultToMap(result);
String id = MapUtils.getString(kvMap, "id");
if (StringUtils.isNotBlank(id)) {
resultMap.put(id, kvMap);
}
});
return resultMap;
}
/**
* 写入 qualifier
*
* @param tableName
* @param rowName
* @param familyName
* @param qualifier
* @param value
* @return
* @throws IOException
*/
public boolean put(String tableName, String rowName, String familyName, String qualifier, String value) throws IOException {
Map<String, String> qv = new HashMap<>();
qv.put(qualifier, value);
put(tableName, rowName, familyName, qv);
return true;
}
/**
* 写入 qualifiers
*
* @param tableName
* @param rowName
* @param familyName
* @param qualifierValues
* @return
* @throws IOException
*/
public boolean put(String tableName, String rowName, String familyName, Map<String, String> qualifierValues) throws IOException {
if (MapUtils.isEmpty(qualifierValues)) {
return false;
}
List<Put> puts = new ArrayList<>();
qualifierValues.forEach((qualifier, value) -> puts.add(new Put(rowName.getBytes()).addColumn(familyName.getBytes(), qualifier.getBytes(), value.getBytes())));
hbaseConnection.getTable(TableName.valueOf(tableName)).put(puts);
return true;
}
/**
* 删除
*
* @param tableName
* @param rowName
* @param familyName
* @return
* @throws IOException
*/
public boolean del(String tableName, String rowName, String familyName) throws IOException {
Delete delete = new Delete(rowName.getBytes());
delete.addFamily(familyName.getBytes());
hbaseConnection.getTable(TableName.valueOf(tableName)).delete(delete);
return true;
}
/**
* 删除 qualifier
*
* @param tableName
* @param rowName
* @param familyName
* @param qualifiers
* @return
* @throws IOException
*/
public boolean delQualifiers(String tableName, String rowName, String familyName, List<String> qualifiers) throws IOException {
Delete delete = new Delete(rowName.getBytes());
qualifiers.forEach(qualifier -> delete.addColumn(familyName.getBytes(), qualifier.getBytes()));
hbaseConnection.getTable(TableName.valueOf(tableName)).delete(delete);
return true;
}
}
getTable:
获取 Table 实现用以访问表数据。
Table 非 thread-safe 的并且其创建很轻量,所以线程内使用需要单独创建(不需要且不应该缓存和池化)。
简简单单用一下 Hbase的更多相关文章
- Hadoop: the definitive guide 第三版 拾遗 第十三章 之HBase起步
指南上这一章的开篇即提出:HBase是一个分布式的.面向列的开源数据库.如果需要实时的随机读/写超大规模数据集,HBase无疑是一个好的选择. 简介 HBase 是一个高可靠性.高性能.面向列.可伸缩 ...
- Hadoop HBase概念学习系列之概念视图(又名为逻辑模型)(八)
其实啊,我们把HBase想象成一个大的映射关系,再者,本来,HBase存储的数据可以理解为一种key和value的映射关系,但有不是简简单单的映射关系那种,因为比如有各个时间戳版本啊. 通过行键.行键 ...
- 一次bug死磕经历之Hbase堆内存小导致regionserver频繁挂掉
环境如下: Centos6.5 Apache Hadoop2.7.1 Apache Hbase0.98.12 Apache Zookeeper3.4.6 JDK1.7 Ant1.9.5 Maven3. ...
- 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase的shell应用v2.0
HRegion 当表的大小超过设置值的时候,HBase会自动地将表划分为不同的区域,每个区域包含所有行的一个子集.对用户来说,每个表是一堆数据的集合,靠主键来区分.从物理上来说,一张表被拆分成了多块, ...
- Mapreduce的文件和hbase共同输入
Mapreduce的文件和hbase共同输入 package duogemap; import java.io.IOException; import org.apache.hadoop.co ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- Hbase的伪分布式安装
Hbase安装模式介绍 单机模式 1> Hbase不使用HDFS,仅使用本地文件系统 2> ZooKeeper与Hbase运行在同一个JVM中 分布式模式– 伪分布式模式1> 所有进 ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- Spark读写Hbase的二种方式对比
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 一.传统方式 这种方式就是常用的TableInputFormat和TableOutputForm ...
随机推荐
- kubernetes证书过期处理
rancher中文文档:http://docs.rancher.cn/ k8s中文文档:https://kubernetes.io/zh/docs 一.修改kubeadm 源码 增加证书到100年 $ ...
- Docker修改默认IP
Docker修改默认IP 删除原有配置 sudo systemctl stop docker sudo ip link set dev docker0 down sudo brctl delbr do ...
- Linux移植到自己的开发板(三)根文件系统
@ 目录 1 Linux内核配置 2 ramdisk制作 3 busybox配置 4 genext2fs生成镜像 为了快速调试,采用ramdisk进行根文件系统测试.要使内核能挂载ramdisk根文件 ...
- logging 日志配用
第一步,创建一个logger: 第二步,创建一个handler,用于写入日志文件: 第三步,再创建一个handler,用于输出到控制台: 第四步,定义handler的输出格式: 第五步,将logger ...
- Windows10运行Cura源代码,搭建环境教程
参考官方文档 https://github.com/Ultimaker/Cura/wiki/Running-Cura-from-Source-on-Windows#python-3810 注意 这些说 ...
- HashMap集合类 5种最佳遍历方式
1. 使用 Iterator 遍历 HashMap EntrySet 2. 使用 Iterator 遍历 HashMap KeySet 3. 使用 For-each 循环迭代 HashMap 4. 使 ...
- mysql join 底层原理
你知道 Sql 中 left join 的底层原理吗? 2019-09-10阅读 7130 https://cloud.tencent.com/developer/column/2367 01.前 ...
- 开启 Spring Boot 特性有哪几种方式?
1)继承spring-boot-starter-parent项目 2)导入spring-boot-dependencies项目依赖
- Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法 ?
面试官:想了解对 ES 集群的运维能力. 解答: 1.关闭缓存 swap; 2.堆内存设置为:Min(节点内存/2, 32GB); 3.设置最大文件句柄数: 4.线程池+队列大小根据业务需要做调整: ...
- Java中hashCode、equals、==的区别
ref:http://www.cnblogs.com/skywang12345/p/3324958.html 1.==作用: java中的==用来判断两个对象的地址是否相等:当对象是基本数据类型时,可 ...