hbase 取多个版本数据

摘要:
常见的应用可以如上所述解决。如果服务器正常,则不会出现问题。然而,如果您想访问多个版本,可能会遇到我遇到的问题。以下代码是否有问题?
http://jiajun.iteye.com/blog/945358

HBase如何存取多个版本的值?

废话少说,一般情况下使用Put的这个方法保存一个版本:

Java代码 收藏代码
  1. /**
  2. *AddthespecifiedcolumnandvaluetothisPutoperation.
  3. *@paramfamilyfamilyname
  4. *@paramqualifiercolumnqualifier
  5. *@paramvaluecolumnvalue
  6. */
  7. publicPutadd(byte[]family,byte[]qualifier,byte[]value){
  8. returnadd(family,qualifier,this.timestamp,value);
  9. }
  10. 然后获取HTable的实例,调用Put方法,更新入库。

这里我要刻意说明一下时间戳 ,可以看到上面的add方面实现里面调用了另外一个方法,增加了个参数:默认时间戳

Java代码 收藏代码
  1. this.timestamp

它的值是:

Java代码 收藏代码
  1. privatelongtimestamp=HConstants.LATEST_TIMESTAMP;
  2. staticfinallongLATEST_TIMESTAMP=Long.MAX_VALUE;

那么获取的时候,获取一个值 也很简单,使用下面的方法:

Java代码 收藏代码
  1. 创建一个Put的实例
  2. /**
  3. *CreateaGetoperationforthespecifiedrow.
  4. *<p>
  5. *Ifnofurtheroperationsaredone,thiswillgetthelatestversionof
  6. *allcolumnsinallfamiliesofthespecifiedrow.
  7. *@paramrowrowkey
  8. */
  9. publicGet(byte[]row){
  10. this(row,null);
  11. }
  12. 然后获取HTable实例调用方法
  13. publicResultget(finalGetget)throwsIOException
  14. 返回的Result对象调用
  15. publicbyte[]getValue(byte[]family,byte[]qualifier)
  16. 就可以获取值。

一般的应用可以像上面这样来解决,服务器正常的话不会碰到什么问题,可是要存取多个版本 的话,有可能你会遇到我遇到的问题。 看下面一段代码是否有问题

(里面有如何插入多个版本 ,如何获取多个版本 的方法,顺带说明一个问题)

Java代码 收藏代码
  1. /**
  2. *Testgetvalueofmultiversions
  3. *
  4. *@authordev-cjj
  5. *
  6. */
  7. publicclassGetRowVersionsTestextendsTestCase
  8. {
  9. privatefinalbyte[]family=Bytes.toBytes("log");
  10. privatefinalbyte[]qualifier=Bytes.toBytes("q1");
  11. privatefinalbyte[]qualifier2=Bytes.toBytes("q2");
  12. privatefinalbyte[]rowKey=Bytes.toBytes(10001);
  13. privatefinalHTabletable=IDMHBaseConfiguration.getTable("testTable");
  14. privatefinallongts1=1298529542218L;
  15. privatefinallongts2=ts1+100;
  16. privatefinallongts3=ts1+1000;
  17. privatefinallongts4=ts1+2000;
  18. privatefinallongts5=ts1+3000;
  19. privatefinalbyte[]value1=Bytes.toBytes("value1");
  20. privatefinalbyte[]value2=Bytes.toBytes("value2");
  21. privatefinalbyte[]value3=Bytes.toBytes("value3");
  22. privatefinalbyte[]value4=Bytes.toBytes("value4");
  23. privatefinalbyte[]value5=Bytes.toBytes("value5");
  24. privatevoidinsert(finallongts,finalbyte[]value)throwsIOException
  25. {
  26. //table.setAutoFlush(false);
  27. finalPutput=newPut(rowKey);
  28. put.add(family,qualifier,ts,value);
  29. put.add(family,qualifier2,ts,value);
  30. table.put(put);
  31. }
  32. privatevoidsleep()
  33. {
  34. try
  35. {
  36. Thread.sleep(1000);
  37. }
  38. catch(finalInterruptedExceptione)
  39. {
  40. e.printStackTrace();
  41. }
  42. }
  43. @Test
  44. publicvoidtestGetRowMultipleVersions()throwsException
  45. {
  46. insert(ts1,value1);
  47. sleep();
  48. insert(ts2,value2);
  49. sleep();
  50. insert(ts3,value3);
  51. sleep();
  52. insert(ts4,value4);
  53. sleep();
  54. insert(ts5,value5);
  55. sleep();
  56. //checkgetRowwithmultipleversions
  57. finalGetget=newGet(rowKey);
  58. get.setMaxVersions();
  59. finalResultr=table.get(get);
  60. //onewaygetvaluesofallversion
  61. //finalList<KeyValue>list=r.list();
  62. //for(finalKeyValuekv:list)
  63. //{
  64. //System.err.println(Bytes.toString(kv.getKey()));
  65. //System.err.println(kv.getTimestamp());
  66. //System.err.println(Bytes.toString(kv.getValue()));
  67. //}
  68. //anotherwaygetvaluesofallversion
  69. finalNavigableMap<byte[],NavigableMap<byte[],NavigableMap<Long,byte[]>>>map=r.getMap();
  70. finalNavigableMap<byte[],NavigableMap<Long,byte[]>>familyMap=map.get(family);
  71. finalNavigableMap<Long,byte[]>versionMap=familyMap.get(qualifier);
  72. for(finalMap.Entry<Long,byte[]>entry:versionMap.entrySet())
  73. {
  74. System.err.println(Bytes.toString(qualifier)+"->"+Bytes.toString(entry.getValue()));
  75. }
  76. finalNavigableMap<Long,byte[]>versionMap2=familyMap.get(qualifier2);
  77. for(finalMap.Entry<Long,byte[]>entry:versionMap2.entrySet())
  78. {
  79. System.err.println(Bytes.toString(qualifier2)+"->"+Bytes.toString(entry.getValue()));
  80. }
  81. //assertTrue(versionMap.size()==5);
  82. //assertTrue(value1==versionMap.get(ts1));
  83. //assertTrue(value2==versionMap.get(ts2));
  84. //assertTrue(value3==versionMap.get(ts3));
  85. //table.delete(newDelete(rowKey));
  86. //assertTrue(table.get(get).size()==0);
  87. //table.close();
  88. }
  89. }

这里我只是打印输出结果 ,不用断言, 结果如你所期望的是:

Java代码 收藏代码
  1. q1->value5
  2. q1->value4
  3. q1->value3
  4. q1->value2
  5. q1->value1
  6. q2->value5
  7. q2->value4
  8. q2->value3
  9. q2->value2
  10. q2->value1

上面的代码中,我注视掉了一个关键行

Java代码 收藏代码
  1. //table.delete(newDelete(rowKey));

如果取消注释,再运行几次你会发现一个大问题! 保存不上了,一个版本都没有。

final Result r = table.get(get); 里面什么都不会有! 很奇怪!

问题原因 (针对上面的代码和问题):

1、插入的时候使用的时间戳都是过去的时间戳。

2、删除的时候没有指定时间戳(如果没有指定则默认一个当前的时间戳)

3、在HBase中删除操作并没有删除对应的文件,只是做一个带有时间戳的删除标记(任何在这个时间戳之前的列值都会被认为是删除的)

那么知道上面三条规则,问题就简单了,新插入的列值的时间戳要在删除标记的时间戳之后,才会被认为是不被删除的列值。

补充一点,创建/添加列族时候默认是三个版本,可以修改为1个版本或者更多个版本,我上面5个版本是因为我指定了5个版本。

Java代码 收藏代码
  1. {NAME=>'testTable',FAMILIES=>[{NAME=>'log',COMPRESSION=>'NONtrue
  2. E',VERSIONS=>'5',TTL=>'2147483647',BLOCKSIZE=>'65536',IN_MEM
  3. ORY=>'false',BLOCKCACHE=>'true'}]}

免责声明:文章转载自《hbase 取多个版本数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SVG矢量绘图 path路径详解(贝塞尔曲线及平滑)推荐一款Silverlight数据列表控件AgDataGrid下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java微信公众平台开发(一)--接入微信公众平台

转自:http://www.cuiyongzhi.com/post/38.html (一)接入流程解析 在我们的开发过程中无论如何最好的参考工具当然是我们的官方文档了:http://mp.weixin.qq.com/wiki/8/f9a0b8382e0b77d87b3bcc1ce6fbc104.html 通过文档我们可以看出其中接入微信公众平台开发,开发者...

Oracle函数应用与查询聚合统计

Oracle预定义函数 Oracle数据库系统中定义了很多的函数(预定义)。这些函数能够完成本身特有的数据操作功能,执行效率更高并重复使用。 Oracle中的预定义函数按照对数据的操作执行特征可以分为: 单行函数——对每个记录执行一次 聚合函数(多行函数)——对多个记录行执行一次 单行函数 字符串函数 日期时间函数 数学计算函数 其它特殊函数 字符串操作函...

hbase完全分布式安装

完全分布式安装 需要一个hadoop集群和hbase集群 为防止服务器宕机导致数据丢失,公司一般采用此模式。如果是个人测试使用,建议安装伪分布式https://www.cnblogs.com/hzcjd/p/13868391.html 1安装hadoop集群 启动hbase前先得启动hadoop 安装方法见 hadoop完全分布式安装https://www...

Interceptors

1.概述 Flume有能力在运行阶段修改/删除Event,这是通过拦截器(Interceptors)来实现的。 拦截器需要实现org.apache.flume.interceptor.Interceptor接口。 拦截器可以修改或删除事件基于开发者在选择器中选择的任何条件。 拦截器采用了责任链模式,多个拦截器可以按指定顺序拦截。 一个拦截器返回的...

字符串编码

在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。 用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件 由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网...

实用向—总结一些唯一ID生成方式

在日常的项目开发中,我们经常会遇到需要生成唯一ID的业务场景,不同的业务对唯一ID的生成方式与要求都会不尽相同,一是生成方式多种多样,如UUID、雪花算法、数据库递增等;其次业务要求上也各有不同,有的只要保证唯一性即可,有的需要加上时间戳,有的要保证按顺序递增等。以下是我结合实际业务中的使用总结了几种唯一ID的生成方式,  要求就是在一般的应用场景下一方面...