专栏首页xingoo, 一个梦想做发明家的程序员Hbase多版本的读写(Shell&Java API版)

Hbase多版本的读写(Shell&Java API版)

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • AVL树

    详细描述,好像跟我自己写的差不多......不过终究是大神级别,讲的就是透彻 1. 概述 AVL树是最早提出的自平衡二叉树,在AVL树中任何节点的两个子树的高度...

    用户1154259
  • 使用计时器-方法2

    第一种方法 是把WM_TIMER消息发送给正常的窗口过程。 第二种方法 是 自己让 windows把计时器消息发送给程序中的另一个窗口过程 回调函数: VOID...

    用户1154259
  • 【AngularJS】—— 8 自定义指令

    AngularJS支持用户自定义标签属性,在不需要使用DOM节点操作的情况下,添加自定义的内容。 前面提到AngularJS的四大特性:   1 MVC ...

    用户1154259
  • 因子建模(附代码)

    用于分析投资组合风险的最受欢迎的模型是因子模型,因为股票具有共同移动的趋势。证券的主要组成部分经常会解释很大一部分差异。由于我们主要关注构成投资组合的多种资产,...

    量化投资与机器学习微信公众号
  • 编译hbase-1.2.3源代码

    确保机器可以正常访问Internet,如能正常访问https://repo.maven.apache.org等,如果是代理方式则需要设置好eclipse和m...

    一见
  • 面试必考点:HBase Compaction机制

    Compaction是buffer->flush->merge的Log-Structured Merge-Tree模型的关键操作,主要起到如下几个作用:

    王知无
  • Quora Question Pairs 竞赛冠军经验分享:采用 4 层堆叠,经典模型比较给力

    AI 研习社按:今天要介绍的比赛是 Quora Question Pairs,该比赛的目的是将具有相同意图的问题正确配对。最近本次竞赛的冠军在 Kaggle 社...

    AI研习社
  • 决策树学习笔记(一):特征选择

    相信很多朋友已经对决策树很熟悉了,决策树是机器学习中的一种基本的可用于分类与回归的方法,它是一些集成学习如GBDT,XGboost等复杂模型的基础。这些高级模型...

    用户2769421
  • 决策树学习笔记(一):特征选择

    相信很多朋友已经对决策树很熟悉了,决策树是机器学习中的一种基本的可用于分类与回归的方法,它是一些集成学习如GBDT,XGboost等复杂模型的基础。这些高级模型...

    1480
  • “年轻时尚且议题不断”的两会,VR/AR、5G、4K、AI频繁被Cue!

    近期,两会正在火热召开中,国内外目光均聚焦于此。而VR/AR、5G、4K、AI等展露锋芒的黑科技,也吸引不少眼球,频繁被Cue。各方真可谓上演了一番“科技看家本...

    VRPinea

扫码关注云+社区

领取腾讯云代金券