zoukankan      html  css  js  c++  java
  • hbase 取多个版本数据

    http://jiajun.iteye.com/blog/945358

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

    
    
    
    
    
    
    
    

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

    
    
    
    
    
    Java代码  收藏代码
    1. /** 
    2.    * Add the specified column and value to this Put operation. 
    3.    * @param family family name 
    4.    * @param qualifier column qualifier 
    5.    * @param value column value 
    6.    */  
    7.   public Put add(byte [] family, byte [] qualifier, byte [] value) {  
    8.     return add(family, qualifier, this.timestamp, value);  
    9.   }  
    10.   
    11. 然后获取HTable的实例,调用Put方法,更新入库。  
     

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

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

    它的值是:

    
    
    Java代码  收藏代码
    1. private long timestamp = HConstants.LATEST_TIMESTAMP;  
    2.   
    3. static final long LATEST_TIMESTAMP = Long.MAX_VALUE;  
     

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

    
    
    Java代码  收藏代码
    1. 创建一个Put的实例  
    2. /** 
    3.    * Create a Get operation for the specified row. 
    4.    * <p> 
    5.    * If no further operations are done, this will get the latest version of 
    6.    * all columns in all families of the specified row. 
    7.    * @param row row key 
    8.    */  
    9.   public Get(byte [] row) {  
    10.     this(row, null);  
    11.   }  
    12.   
    13. 然后获取HTable实例调用方法   
    14. public Result get(final Get get) throws IOException  
    15.   
    16. 返回的Result对象 调用   
    17.  public byte [] getValue(byte [] family, byte [] qualifier)  
    18.   
    19. 就可以获取值。  
    
    
    
    
    

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

    
    
    
    
    

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

    
    
    
    
    
    Java代码  收藏代码
    1. /** 
    2.  * Test get value of multi versions 
    3.  *  
    4.  * @author dev-cjj 
    5.  *  
    6.  */  
    7. public class GetRowVersionsTest extends TestCase  
    8. {  
    9.     private final byte[] family     = Bytes.toBytes("log");  
    10.   
    11.     private final byte[] qualifier  = Bytes.toBytes("q1");  
    12.   
    13.     private final byte[] qualifier2 = Bytes.toBytes("q2");  
    14.   
    15.     private final byte[] rowKey     = Bytes.toBytes(10001);  
    16.   
    17.     private final HTable table      = IDMHBaseConfiguration.getTable("testTable");  
    18.   
    19.     private final long   ts1        = 1298529542218L;  
    20.   
    21.     private final long   ts2        = ts1 + 100;  
    22.   
    23.     private final long   ts3        = ts1 + 1000;  
    24.   
    25.     private final long   ts4        = ts1 + 2000;  
    26.   
    27.     private final long   ts5        = ts1 + 3000;  
    28.   
    29.     private final byte[] value1     = Bytes.toBytes("value1");  
    30.   
    31.     private final byte[] value2     = Bytes.toBytes("value2");  
    32.   
    33.     private final byte[] value3     = Bytes.toBytes("value3");  
    34.   
    35.     private final byte[] value4     = Bytes.toBytes("value4");  
    36.   
    37.     private final byte[] value5     = Bytes.toBytes("value5");  
    38.   
    39.     private void insert(final long ts, final byte[] value) throws IOException  
    40.     {  
    41.         //        table.setAutoFlush(false);  
    42.         final Put put = new Put(rowKey);  
    43.         put.add(family, qualifier, ts, value);  
    44.         put.add(family, qualifier2, ts, value);  
    45.         table.put(put);  
    46.     }  
    47.   
    48.     private void sleep()  
    49.     {  
    50.         try  
    51.         {  
    52.             Thread.sleep(1000);  
    53.         }  
    54.         catch (final InterruptedException e)  
    55.         {  
    56.             e.printStackTrace();  
    57.         }  
    58.     }  
    59.   
    60.     @Test  
    61.     public void testGetRowMultipleVersions() throws Exception  
    62.     {  
    63.         insert(ts1, value1);  
    64.         sleep();  
    65.         insert(ts2, value2);  
    66.         sleep();  
    67.         insert(ts3, value3);  
    68.         sleep();  
    69.         insert(ts4, value4);  
    70.         sleep();  
    71.         insert(ts5, value5);  
    72.         sleep();  
    73.   
    74.         // check getRow with multiple versions  
    75.         final Get get = new Get(rowKey);  
    76.         get.setMaxVersions();  
    77.         final Result r = table.get(get);  
    78.   
    79.         // one way get values of all version  
    80.         //        final List<KeyValue> list = r.list();  
    81.         //        for (final KeyValue kv : list)  
    82.         //        {  
    83.         //            System.err.println(Bytes.toString(kv.getKey()));  
    84.         //            System.err.println(kv.getTimestamp());  
    85.         //            System.err.println(Bytes.toString(kv.getValue()));  
    86.         //        }  
    87.   
    88.         // another way get values of all version  
    89.         final NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = r.getMap();  
    90.         final NavigableMap<byte[], NavigableMap<Long, byte[]>> familyMap = map.get(family);  
    91.         final NavigableMap<Long, byte[]> versionMap = familyMap.get(qualifier);  
    92.         for (final Map.Entry<Long, byte[]> entry : versionMap.entrySet())  
    93.         {  
    94.             System.err.println(Bytes.toString(qualifier) + " -> " + Bytes.toString(entry.getValue()));  
    95.         }  
    96.   
    97.         final NavigableMap<Long, byte[]> versionMap2 = familyMap.get(qualifier2);  
    98.         for (final Map.Entry<Long, byte[]> entry : versionMap2.entrySet())  
    99.         {  
    100.             System.err.println(Bytes.toString(qualifier2) + " -> " + Bytes.toString(entry.getValue()));  
    101.         }  
    102.   
    103.         //        assertTrue(versionMap.size() == 5);  
    104.   
    105.         //        assertTrue(value1 == versionMap.get(ts1));  
    106.         //        assertTrue(value2 == versionMap.get(ts2));  
    107.         //        assertTrue(value3 == versionMap.get(ts3));  
    108.   
    109.         //        table.delete(new Delete(rowKey));  
    110.   
    111.         //        assertTrue(table.get(get).size() == 0);  
    112.         //        table.close();  
    113.     }  
    114. }  
     

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

    
    
    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(new Delete(rowKey));  
    
    

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

    
    
    
    
    

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

    
    
    
    
    

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

    
    
    
    
    

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

    
    

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

    
    

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

    
    
    
    
    

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

    
    
    
    
    

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

    
    
    Java代码  收藏代码
    1. {NAME => 'testTable', FAMILIES => [{NAME => 'log', COMPRESSION => 'NON true                        
    2.  E', VERSIONS => '5', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEM                             
    3.  ORY => 'false', BLOCKCACHE => 'true'}]}    
     
  • 相关阅读:
    迭代器模式
    工厂方法模式
    ajax发送多个跨域请求回调不混乱
    Java中&和&&的区别
    使用jstl方式替换服务器请求地址
    用jinja2替换Django的模板
    Django在apache中的配置
    从word中提取图片的三种方法
    IE中出现 "Stack overflow at line" 错误的解决方法
    c# 空接合(??)运算符的运用
  • 原文地址:https://www.cnblogs.com/i80386/p/3953226.html
Copyright © 2011-2022 走看看