hbase 取多个版本数据
http://jiajun.iteye.com/blog/945358
HBase如何存取多个版本的值?
废话少说,一般情况下使用Put的这个方法保存一个版本:
- /**
- * Add the specified column and value to this Put operation.
- * @param family family name
- * @param qualifier column qualifier
- * @param value column value
- */
- public Put add(byte [] family, byte [] qualifier, byte [] value) {
- return add(family, qualifier, this.timestamp, value);
- }
- 然后获取HTable的实例,调用Put方法,更新入库。
这里我要刻意说明一下时间戳 ,可以看到上面的add方面实现里面调用了另外一个方法,增加了个参数:默认时间戳
- this.timestamp
它的值是:
- private long timestamp = HConstants.LATEST_TIMESTAMP;
- static final long LATEST_TIMESTAMP = Long.MAX_VALUE;
那么获取的时候,获取一个值 也很简单,使用下面的方法:
- 创建一个Put的实例
- /**
- * Create a Get operation for the specified row.
- * <p>
- * If no further operations are done, this will get the latest version of
- * all columns in all families of the specified row.
- * @param row row key
- */
- public Get(byte [] row) {
- this(row, null);
- }
- 然后获取HTable实例调用方法
- public Result get(final Get get) throws IOException
- 返回的Result对象 调用
- public byte [] getValue(byte [] family, byte [] qualifier)
- 就可以获取值。
一般的应用可以像上面这样来解决,服务器正常的话不会碰到什么问题,可是要存取多个版本 的话,有可能你会遇到我遇到的问题。 看下面一段代码是否有问题 ?
(里面有如何插入多个版本 ,如何获取多个版本 的方法,顺带说明一个问题)
- /**
- * Test get value of multi versions
- *
- * @author dev-cjj
- *
- */
- public class GetRowVersionsTest extends TestCase
- {
- private final byte[] family = Bytes.toBytes("log");
- private final byte[] qualifier = Bytes.toBytes("q1");
- private final byte[] qualifier2 = Bytes.toBytes("q2");
- private final byte[] rowKey = Bytes.toBytes(10001);
- private final HTable table = IDMHBaseConfiguration.getTable("testTable");
- private final long ts1 = 1298529542218L;
- private final long ts2 = ts1 + 100;
- private final long ts3 = ts1 + 1000;
- private final long ts4 = ts1 + 2000;
- private final long ts5 = ts1 + 3000;
- private final byte[] value1 = Bytes.toBytes("value1");
- private final byte[] value2 = Bytes.toBytes("value2");
- private final byte[] value3 = Bytes.toBytes("value3");
- private final byte[] value4 = Bytes.toBytes("value4");
- private final byte[] value5 = Bytes.toBytes("value5");
- private void insert(final long ts, final byte[] value) throws IOException
- {
- // table.setAutoFlush(false);
- final Put put = new Put(rowKey);
- put.add(family, qualifier, ts, value);
- put.add(family, qualifier2, ts, value);
- table.put(put);
- }
- private void sleep()
- {
- try
- {
- Thread.sleep(1000);
- }
- catch (final InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- @Test
- public void testGetRowMultipleVersions() throws Exception
- {
- insert(ts1, value1);
- sleep();
- insert(ts2, value2);
- sleep();
- insert(ts3, value3);
- sleep();
- insert(ts4, value4);
- sleep();
- insert(ts5, value5);
- sleep();
- // check getRow with multiple versions
- final Get get = new Get(rowKey);
- get.setMaxVersions();
- final Result r = table.get(get);
- // one way get values of all version
- // final List<KeyValue> list = r.list();
- // for (final KeyValue kv : list)
- // {
- // System.err.println(Bytes.toString(kv.getKey()));
- // System.err.println(kv.getTimestamp());
- // System.err.println(Bytes.toString(kv.getValue()));
- // }
- // another way get values of all version
- final NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = r.getMap();
- final NavigableMap<byte[], NavigableMap<Long, byte[]>> familyMap = map.get(family);
- final NavigableMap<Long, byte[]> versionMap = familyMap.get(qualifier);
- for (final Map.Entry<Long, byte[]> entry : versionMap.entrySet())
- {
- System.err.println(Bytes.toString(qualifier) + " -> " + Bytes.toString(entry.getValue()));
- }
- final NavigableMap<Long, byte[]> versionMap2 = familyMap.get(qualifier2);
- for (final Map.Entry<Long, byte[]> entry : versionMap2.entrySet())
- {
- System.err.println(Bytes.toString(qualifier2) + " -> " + Bytes.toString(entry.getValue()));
- }
- // assertTrue(versionMap.size() == 5);
- // assertTrue(value1 == versionMap.get(ts1));
- // assertTrue(value2 == versionMap.get(ts2));
- // assertTrue(value3 == versionMap.get(ts3));
- // table.delete(new Delete(rowKey));
- // assertTrue(table.get(get).size() == 0);
- // table.close();
- }
- }
这里我只是打印输出结果 ,不用断言, 结果如你所期望的是:
- q1 -> value5
- q1 -> value4
- q1 -> value3
- q1 -> value2
- q1 -> value1
- q2 -> value5
- q2 -> value4
- q2 -> value3
- q2 -> value2
- q2 -> value1
上面的代码中,我注视掉了一个关键行
- // table.delete(new Delete(rowKey));
如果取消注释,再运行几次你会发现一个大问题! 保存不上了,一个版本都没有。
final Result r = table.get(get); 里面什么都不会有! 很奇怪!
问题原因 (针对上面的代码和问题):
1、插入的时候使用的时间戳都是过去的时间戳。
2、删除的时候没有指定时间戳(如果没有指定则默认一个当前的时间戳)
3、在HBase中删除操作并没有删除对应的文件,只是做一个带有时间戳的删除标记(任何在这个时间戳之前的列值都会被认为是删除的)
那么知道上面三条规则,问题就简单了,新插入的列值的时间戳要在删除标记的时间戳之后,才会被认为是不被删除的列值。
补充一点,创建/添加列族时候默认是三个版本,可以修改为1个版本或者更多个版本,我上面5个版本是因为我指定了5个版本。
- {NAME => 'testTable', FAMILIES => [{NAME => 'log', COMPRESSION => 'NON true
- E', VERSIONS => '5', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEM
- ORY => 'false', BLOCKCACHE => 'true'}]}
hbase 取多个版本数据的更多相关文章
- HBase跨版本数据迁移总结
某客户大数据测试场景为:Solr类似画像的数据查出用户标签--通过这些标签在HBase查询详细信息.以上测试功能以及性能. 其中HBase的数据量为500G,Solr约5T.数据均需要从对方的集群人工 ...
- 【hbase】——bulk load导入数据时value=\x00\x00\x00\x01问题解析
一.存入数据类型 Hbase里面,rowkey是按照字典序进行排序.存储的value值,当用filter进行数据筛选的时候,所用的比较算法也是字典序的. 1.当存储的value值是float类型的时候 ...
- Python小爬虫——抓取豆瓣电影Top250数据
python抓取豆瓣电影Top250数据 1.豆瓣地址:https://movie.douban.com/top250?start=25&filter= 2.主要流程是抓取该网址下的Top25 ...
- 实现HBase增量入库(HBase删除自定义时间戳行数据)
目录 1. 背景描述 2. 问题描述 3. 解决方案 1. 背景描述 目前在做音乐推荐项目,前期做排序模型优化,任务是使用模型对用户的历史音乐进行排序,有6800多万个用户,约40G的用户数据,使用H ...
- Python 3.6 抓取微博m站数据
Python 3.6 抓取微博m站数据 2019.05.01 更新内容 containerid 可以通过 "107603" + user_id 组装得到,无需请求个人信息获取: 优 ...
- 使用python抓取婚恋网用户数据并用决策树生成自己择偶观
最近在看<机器学习实战>的时候萌生了一个想法,自己去网上爬一些数据按照书上的方法处理一下,不仅可以加深自己对书本的理解,顺便还可以在github拉拉人气.刚好在看决策树这一章,书里面的理论 ...
- 使用 Python 抓取欧洲足球联赛数据
Web Scraping在大数据时代,一切都要用数据来说话,大数据处理的过程一般需要经过以下的几个步骤 数据的采集和获取 数据的清洗,抽取,变形和装载 数据的分析,探索和预测 ...
- 抓取Js动态生成数据且以滚动页面方式分页的网页
代码也可以从我的开源项目HtmlExtractor中获取. 当我们在进行数据抓取的时候,如果目标网站是以Js的方式动态生成数据且以滚动页面的方式进行分页,那么我们该如何抓取呢? 如类似今日头条这样的网 ...
- 如何用python抓取js生成的数据 - SegmentFault
如何用python抓取js生成的数据 - SegmentFault 如何用python抓取js生成的数据 1赞 踩 收藏 想写一个爬虫,但是需要抓去的的数据是js生成的,在源代码里看不到,要怎么才能抓 ...
随机推荐
- 我终于理解了LISP『代码即数据|数据即代码』的含义
以前我一直不能理解LISP里引用的作用,感觉引用和字符串没什么区别.比如:> (define (func) 'ok) > (func) 'ok 这里把引用ok当做了函数func的返 ...
- update目标在查询返回结果集中的解决方案
示例: students为学生信息表 Score为成绩表 两个表通过学生号关联 要求:将总成绩小于100的学生名称改为‘天才’ sql如下: error提示:update目标不能在查询返回结果集中 ...
- 【C语言】03-printf和scanf函数
一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据 1.用法 1> pr ...
- Bootstrap--组件之Glyphicons字体图标
Glyphicons 字体图标 所有可用的图标 包括250多个来自 Glyphicon Halflings 的字体图标.Glyphicons Halflings 一般是收费的,但是他们的作者允许 Bo ...
- 使用PSSH批量SSH操作Linux服务器
http://www.opstool.com/article/266 服务器多了,有一个烦恼就是如何批量快速操作一堆服务器.这里我推荐一下经常使用利器pssh.这个工具给我的工作带来了莫大的帮助. 简 ...
- 第一次使用并配置Hibernate
1. 环境配置 1.1 hiberante环境配置 hibernate可实现面向对象的数据存储.hibernate的官网:http://hibernate.org/ 官网上选择hibernate OR ...
- oc语言学习之基础知识点介绍(五):OC进阶
一.点语法介绍 /* 以前封装后,要给属性赋值,必须调用方法 这样做,有两个缺点: 1.代码量多,调用方法要写的东西多. 2.看起来并不像是给属性赋值,也不像取值. 我们用点语法就可以更好的解决! 点 ...
- html表单-双向绑定
潜水多年.一直是只看不评不写多年,每每看到各位大牛分享的经典文章都是默默的收藏,对大牛技术分享技术表示感谢,这么多年从博客园学到了很多. 这段时间项目告一段落. 正好这段时间相对清闲,我也整理一些常用 ...
- DOM4j--write
import java.io.File; import java.io.FileNotFoundException;import java.io.FileOutputStream;import jav ...
- WIX Custom Action (immediate, deffered, rollback)
Following content is directly reprinted from From MSI to WiX, Part 19 - The Art of Custom Action, Pa ...