Hbase是基于HDFS的NOsql数据库,它很多地方跟数据库差不多,也有很多不同的地方。这里就不一一列举了,不过Hbase有个版本控制的特性,这个特性在很多场景下都会发挥很大的作用。本篇就介绍下基于ShellJava API的Hbase多版本的读写。

为了更好的理解多版本,我们可以把普通的数据存储理解成二维空间,提供了rowkey,列族,列几个存储的维度。那么版本则相当于二维空间升华到了三维空间,多了时间维度的概念。如果按照默认的操作,当前的时间戳就是版本号,每个数据都可以保留多个版本的数据。你可以只查询最新的数据,也可以查看历史版本。

这里课外引申一下:从一维到十维空间,有兴趣的可以看一下。 <-- 不要当真哈!从思维开始就已经扯淡了!

上个月在阅读《三体》的时候,也很感叹最后都是多维空间拯救了人类!

话题扯远了,回过来我们在看一下多版本如何进行读写

第一步,创建表并开启多版本

hbase(main):002:0> create_namespace 'xingoo'
0 row(s) in 0.0230 seconds hbase(main):003:0> create 'xingoo:test_v','v'
0 row(s) in 4.5760 seconds => Hbase::Table - xingoo:test_v

创建Hbase表,并查看表结构:

hbase(main):004:0> describe 'xingoo:test_v'
Table xingoo:test_v is ENABLED
xingoo:test_v
COLUMN FAMILIES DESCRIPTION
{NAME => 'v', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TT
L => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}
1 row(s) in 0.1040 seconds

需要关注的是VERSIONS字段,这个字段默认为1,即默认只保留一个版本的数据,如果不修改,无论你怎么写,都只能查到一个版本的数据。

更多参数信息,可以查看HColumnDescriptor的Java Doc

修改版本数

hbase(main):005:0> alter 'xingoo:test_v',NAME=>'v',VERSIONS=>5
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 3.1590 seconds hbase(main):006:0> describe 'xingoo:test_v'
Table xingoo:test_v is ENABLED
xingoo:test_v
COLUMN FAMILIES DESCRIPTION
{NAME => 'v', BLOOMFILTER => 'ROW', VERSIONS => '5', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TT
L => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}
1 row(s) in 0.0150 seconds

再次查看下,就可以看到支持的版本多了。

基于Shell的读写

shell写入多个版本

hbase(main):007:0> put 'xingoo:test_v','1','v:c1','value1'
0 row(s) in 0.0870 seconds hbase(main):008:0> put 'xingoo:test_v','1','v:c1','value2'
0 row(s) in 0.0050 seconds hbase(main):009:0> put 'xingoo:test_v','1','v:c1','value3'
0 row(s) in 0.0040 seconds hbase(main):010:0> put 'xingoo:test_v','1','v:c1','value4'
0 row(s) in 0.0040 seconds hbase(main):011:0> put 'xingoo:test_v','1','v:c1','value5'
0 row(s) in 0.0040 seconds hbase(main):012:0> put 'xingoo:test_v','1','v:c1','value6'
0 row(s) in 0.0030 seconds hbase(main):013:0> put 'xingoo:test_v','1','v:c1','value7'
0 row(s) in 0.0040 seconds

shell读取多个版本的数据

注意:如果读取的版本大于Hbase存储的版本,那么只会读取最大VESIONS个记录。

hbase(main):015:0> get 'xingoo:test_v','1',{COLUMN => 'v:c1',VERSIONS=>5}
COLUMN CELL
v:c1 timestamp=1499088390024, value=value7
v:c1 timestamp=1499088387559, value=value6
v:c1 timestamp=1499088385347, value=value5
v:c1 timestamp=1499088383228, value=value4
v:c1 timestamp=1499088380943, value=value3
5 row(s) in 0.0070 seconds hbase(main):016:0> get 'xingoo:test_v','1',{COLUMN => 'v:c1',VERSIONS=>6}
COLUMN CELL
v:c1 timestamp=1499088390024, value=value7
v:c1 timestamp=1499088387559, value=value6
v:c1 timestamp=1499088385347, value=value5
v:c1 timestamp=1499088383228, value=value4
v:c1 timestamp=1499088380943, value=value3
5 row(s) in 0.0050 seconds hbase(main):017:0> get 'xingoo:test_v','1',{COLUMN => 'v:c1',VERSIONS=>2}
COLUMN CELL
v:c1 timestamp=1499088390024, value=value7
v:c1 timestamp=1499088387559, value=value6
2 row(s) in 0.0060 seconds

另外,还可以把版本字段当做一个时间字段来进行范围查询,如:

hbase> get 't1', 'r1', {COLUMN => 'c1', TIMERANGE => [ts1, ts2], VERSIONS => 4}

基于Java的读写

首先,需要创建工具类,包含连接的配置

public class HbaseClient {
public static final String TABLE = "xingoo:test_v"; private static Configuration conf = null;
private static Connection conn = null; static {
try {
conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.property.clientPort", "2181");
conf.set("hbase.zookeeper.quorum", "zk1,zk2,zk3");
conn = ConnectionFactory.createConnection(conf);
} catch (IOException e) {
e.printStackTrace();
}
}
...
}

读操作

public void write(String phone,String listing_id) throws IOException {
HTable myTable = new HTable(conf, TableName.valueOf(TABLE));
myTable.setAutoFlush(false, false);
myTable.setWriteBufferSize(3 * 1024 * 1024);
Put p = new Put(Bytes.toBytes("row_key_1"));
//可以自己设置时间戳作为版本号,也可以使用默认时间
// p.addColumn(Bytes.toBytes("v"), Bytes.toBytes("c1"), System.currentTimeMillis(), Bytes.toBytes("test1"));
p.addColumn(Bytes.toBytes("v"), Bytes.toBytes("c1"), Bytes.toBytes("test2"));
System.out.println(System.currentTimeMillis());
myTable.put(p);
myTable.flushCommits();
myTable.close();
}

写操作

    public List<String> read(String q) throws IOException {
Table table = HbaseClient.conn.getTable(TableName.valueOf(TABLE));
Scan scan = new Scan();
scan.addColumn("v".getBytes(),"c1".getBytes());
scan.setMaxVersions(3);//设置读取的最大的版本数
RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,new BinaryComparator(q.getBytes()));//基于过滤器设置查询条件
scan.setFilter(rowFilter);
ResultScanner r = table.getScanner(scan);
List<String> list = new ArrayList<>();
for(Result result : r) {
for (KeyValue kv : result.raw()) {
list.add(Bytes.toString(kv.getValue()));
}
}
System.out.println(list.size());
table.close();
return list;
}

参考

1 hbase教程:http://www.yiibai.com/hbase/

2 hbase官方文档:http://hbase.apache.org/book.html#appendix_contributing_to_documentation

3 一维到十维空间:http://www.sohu.com/a/116444282_482877

Hbase多版本的读写(Shell&Java API版)的更多相关文章

  1. HBase学习(二) 基本命令 Java api

    一.Hbase shell 1.Region信息观察 创建表指定命名空间 在创建表的时候可以选择创建到bigdata17这个namespace中,如何实现呢? 使用这种格式即可:'命名空间名称:表名' ...

  2. HBase总结(十二)Java API 与HBase交互实例

    HBase提供了Java Api的訪问接口,掌握这个就跟Java应用使用RDBMS时须要JDBC一样重要 import java.io.IOException; import org.apache.h ...

  3. Hbase学习(三)过滤器 java API

    Hbase学习(三)过滤器 HBase 的基本 API,包括增.删.改.查等. 增.删都是相对简单的操作,与传统的 RDBMS 相比,这里的查询操作略显苍白,只能根据特性的行键进行查询(Get)或者根 ...

  4. HBase根据Rowkey批量查询数据JAVA API(一次查多条,返回多个记录)

    最近在生产中遇到了一个需求,前台给我多个rowkey的List,要在hbase中查询多个记录(返回给前台list).在网上也查了很多,不过自己都不太满意,filter的功能有可能查询结果不是准确值,而 ...

  5. Hbase框架原理及相关的知识点理解、Hbase访问MapReduce、Hbase访问Java API、Hbase shell及Hbase性能优化总结

    转自:http://blog.csdn.net/zhongwen7710/article/details/39577431 本blog的内容包含: 第一部分:Hbase框架原理理解 第二部分:Hbas ...

  6. HBase环境搭建、shell操作及Java API编程

    一. 1.掌握Hbase在Hadoop集群体系结构中发挥的作用和使过程. 2.掌握安装和配置HBase基本方法. 3.掌握HBase shell的常用命令. 4.使用HBase shell命令进行表的 ...

  7. HBase操作(Shell与Java API)

    版权声明:本文为博主原创文章,未经博主允许不得转载.     转: http://blog.csdn.net/u013980127/article/details/52443155 下面代码在Hado ...

  8. hbase java api样例(版本1.3.1,新API)

    hbase版本:1.3.1 目的:HBase新API的使用方法. 尝试并验证了如下几种java api的使用方法. 1.创建表 2.创建表(预分区) 3.单条插入 4.批量插入 5.批量插入(客户端缓 ...

  9. HBase 相关API操练(二):Java API

    一.HBase Java编程 (1)HBase是用Java语言编写的,它支持Java编程: (2)HBase支持CRUD操作:Create,Read,Update和Delete: (3)Java AP ...

随机推荐

  1. elasticsearch5.0.1安装 marvel 插件

    elasticsearch5.0.1安装 marvel 插件 1.在elasticsearch上安装x-pach插件 在elasticsearch的根目录(每个节点),运行 bin/elasticse ...

  2. IDEA测试结果查看

    点击漏斗图标切换查看测试日志信息,点击,导出测试报告

  3. hdu1506单调栈的宽度

    很好的题目,单调栈上的宽度如何求 题解:https://blog.csdn.net/baidu_35643793/article/details/64440095 单调队列和单调栈都是去除没有用的数据 ...

  4. python 全栈开发,Day45(html介绍和head标签,body标签中相关标签)

    一.html介绍 1.web标准 web准备介绍: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web准备规范的分类:结构标准.表现标准.行为标准. 结构 ...

  5. JSON.NET 空值处理, 数字转字符,时间格式化

    public static string ToJsonString(this Object obj) { IsoDateTimeConverter idtc = new IsoDateTimeConv ...

  6. 【算法】后缀自动机(SAM) 例题

    算法介绍见:http://www.cnblogs.com/Sakits/p/8232402.html 广义SAM资料:https://www.cnblogs.com/phile/p/4511571.h ...

  7. Python列表split方法

    转载自:https://www.cnblogs.com/douzi2/p/5579651.html 1.split翻译为分裂.  split()就是将一个字符串分裂成多个字符串组成的列表. 2.spl ...

  8. BZOJ1367 [Baltic2004]sequence 堆 左偏树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...

  9. 069 Hue协作框架

    一:介绍 1.官网 官网:http://gethue.com/ 下载:http://archive.cloudera.com/cdh5/cdh/5/,只能在这里下载,不是Apache的 手册:http ...

  10. docker容器中安装vim 、telnet、ifconfig, ping命令

    在使用docker容器时,有时候里边没有安装vim,敲vim命令时提示说:vim: command not found,这个时候就需要安装vim,可是当你敲apt-get install vim命令时 ...