`

HBase如何存取多个版本的值

阅读更多

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'}]}  
 

 

 

 

7
4
分享到:
评论
1 楼 hanwei59 2011-10-21  
请问如何从多版本中获取最新版本呢?
setMaxVersions只是设置返回的版本数,并不是最新版本。
setTimeRange和setTimeStamp可以指定时间戳,但是我要从多个列中查询数据,每个列的时间戳是不一样的(有的列可能后来修改了数据)
请问有办法同时获取每个列的最新版本数据吗?

相关推荐

    HBase实现批量存取

    我们可以创建一个`Put`对象,设置行键(Row Key)、列族(Column Family)、列(Qualifier)以及对应的值,然后将这些`Put`对象放入`List`中,最后通过`HTable`的`put(List)`方法一次性提交所有更新。这种方法减少了...

    java-hbase开发包

    这个开发包使得Java程序员可以方便地在Java应用程序中存取HBase中的数据。 在"java-hbase-1.2.X"版本中,X表示具体的次要版本号,如1.2.3。此版本可能包含了对HBase 1.2系列稳定性的改进和一些新特性。开发者应当...

    java代码使用thrift2操作hbase示例

    通过这些示例,你可以更好地理解如何在实际项目中整合Java、Thrift2和HBase,以实现高效的数据存取。记住,实践是检验理论的最好方法,所以尝试运行这些示例,根据需求进行调整,你会发现自己的技能会得到显著提升。

    hbase-0.98.8-src.tar.gz

    5. 时间戳:每个单元格(由行键、列限定符和时间戳定义)可以有多个版本,时间戳用于区分同一单元格的不同值。 HBase的主要特点: 1. 分布式:HBase在Hadoop上运行,可以轻松扩展到数千台服务器,处理PB级别的数据...

    高可用HBase的技术实践

    阿里巴巴自2011年5月开始使用HBase,至今已有超过200个业务在使用HBase,并且分布在10多个数据中心。单个HBase集群可达到上千台服务器的规模。HBase在阿里巴巴的应用主要包括以下几个方面: 1. **在线存取**:用于...

    Hbase行键设计(rowkey)实现多条件查询

    本文主要讨论的是如何通过位运算的比较器来实现多条件查询,这种设计方法是针对那些需要查询多个列值的场景。首先,我们需要遵循RowKey设计的一些基本原则: 1. **长度越短越好**:RowKey的长度直接影响到存储空间...

    Hbase中多版本(version)数据获取办法

    本文来自于csdn ,本文介绍2种获取列的多版本数据的方式:shell和spring...从上面的表结构中,我们可以看到,VERSIONS为1,也就是说,默认情况只会存取一个版本的列数据,当再次插入的时候,后面的值会覆盖前面的值。

    HBase专场:AliHBase的SQL实践与改进(天穆 ).pdf

    一是通过哈希散列(Hash散列)的方式,将数据分散到多个Region中,这样可以确保所有Region都可以接受写入,但代价是范围查询时需要并发查询多个Region,然后在客户端进行合并排序。二是采用分桶策略(Bucketing),...

    hbase的表结构及客户端依赖.zip

    7. Region:表被分割成多个Region,Region是HBase的基本存储和检索单位。Region按行键的排序范围划分,随着数据的增长,Region会自动分裂以保持负载均衡。 8. StoreFile:Region内的数据被组织成StoreFile,是HBase...

    hbase0.97官方中文文档

    - 时间戳:每个值都有一个时间戳,用于版本控制和数据保留策略。 2. **架构** - Region:表被分割成多个Region,每个Region由一个Region Server管理。Region按行键范围划分,随着数据增长自动分裂。 - Region ...

    Hadoop技术HBase系统架构共12页.pdf.zip

    每个RegionServer可以管理多个Region,Region是HBase中的基本存储单元,根据行键排序。 4. Region分裂:随着数据的增长,一个Region可能会变得过大,这时HBase会自动分裂Region,将一个Region分为两个,以保持数据...

    hbase基本原理PPT教案.pptx

    4. **Time Stamp**:每个单元格(Cell)都有时间戳,用于记录数据的版本,实现多版本并发控制。 5. **Cell**:Cell是HBase的最小存储单元,包含特定Row Key、Column Family、Qualifier和Timestamp的值。 HBase的...

    hbase访问方式之javaapi共3页.pdf.zip

    HBase的数据模型基于列族,每个表由行和列族组成,列族下可以有任意多的列。 二、Java API概述 HBase提供了丰富的Java API,允许开发者创建、删除表,插入、查询和更新数据,以及管理表分区等。主要类包括HBase...

    大数据技术分享 Hadoop技术分享 阿里HBase在搜索领域的设计与实践 共28页.pdf

    阿里的搜索服务可能需要处理亿级甚至十亿级的文档,HBase可以提供快速的数据存取,支持高效的全文检索和实时更新。此外,HBase的表模型允许快速定位到特定数据,使得搜索引擎能够迅速响应用户的查询请求。 HBase在...

    《大数据平台搭建与配置管理》期末考试卷及答案.docx

    - **知识点**: 表在水平方向由一个或多个列族(Column Family)组成,每个列族包含多个列。 38. **HBase的索引方式** - **知识点**: HBase采用Row Key、Column Family、Column Qualifier和Timestamp四种方式来...

    Java下的大数据分析程序.zip

    在Java环境下进行大数据分析,通常涉及多个关键技术领域,如数据处理、分布式计算、存储系统以及相关的框架和工具。"Java下的大数据分析程序.zip"可能包含一个项目或一系列用于执行大数据分析任务的Java代码。让我们...

    毕业设计:基于spark的外卖大数据平台分析系统.zip

    3. 数据存储:数据可能存储在HDFS(Hadoop分布式文件系统)、HBase等分布式数据库中,以支持大规模数据的存取。 4. 数据清洗与预处理:去除重复数据,处理缺失值,数据类型转换,以及异常值检测和过滤,确保分析...

    云计算环境中的数据挖掘存储管理设计.pdf

    从上述内容可以看出,设计一个符合特定需求的云计算环境下的数据挖掘存储管理方案需要综合考虑数据划分、数据存储策略以及节点划分策略等多个方面的因素。而针对不同行业、不同企业、不同业务需求,这种方案还需要...

    分析Flickr数据集.zip

    同时,数据存储通常采用NoSQL数据库,如HBase或Cassandra,它们能支持大规模、非结构化数据的快速存取。 三、数据采集与清洗 在数据采集阶段,我们可能需要用到网络爬虫技术,如Python的Scrapy框架,来自动化抓取...

Global site tag (gtag.js) - Google Analytics