HBase 关于Versions以及TimeStamp操作总结。

HBase 关于Versions以及TimeStamp操作总结。

转自 https://blog.csdn.net/yulin_hu/article/details/81673331

说明

hbase在建表的时候,一个列族可以指定一个versions,用以表示所存数据的版本数,默认该值为3,即保存最近的3个版本的数据。在每一个cell中有同一数据的多个版本,按时间倒序排序。我们可以在建表的时候指定versions,在放数据的时候以一个时间戳(一个long值)来表示该数据的版本号。取数据时可以取最新的数据,也可以取特定时间戳的数据,某段时间戳的数据以及全部数据。下面将分别给出实示例说明。

示例及解释

  1. 建表,指定versions。
    下面的示例是一个简单的建表语句,我们为testFamily列族指定versions为Int.MaxValue,即会按照时间戳保存Int.MaxValue这个量的数据。setMaxVersions这个方法是针对列族而言的,该versions对该列族下面的每一个列都成立,如有多个列族则需要分别指定。
   val conf = hBaseConfig.getConfiguration
   val connection = ConnectionFactory.createConnection(conf)
   val admin = connection.getAdmin

   val tableNameObj = TableName.valueOf("hbaseTest")
   val hTableDescriptor = new HTableDescriptor(tableNameObj)
   val hColumnDescriptor = new HColumnDescriptor(Bytes.toBytes("testFamily"))
   hColumnDescriptor.setMaxVersions(Int.MaxValue)
   hTableDescriptor.addFamily(hColumnDescriptor)
   admin.createTable(hTableDescriptor)
  1. put数据。
    我们在刚建的hbaseTest表,testFamily列族下面进行操作。我们put的数据是以“row”为RowKey,”q1”,”q2”两个列,分别向其中put不同的数,时间戳依次递增。也就是我们在一个cell中put了多个不同时间戳的数据,
    这里主要调用的api为Put下:
    Put addColumn(byte [] family, byte [] qualifier, long ts, byte [] value)其中ts即时间戳,我们这里分别设定为0-100和0-200
   val put=new Put(Bytes.toBytes("row"))
   for(i<-0 to 100){
     put.addColumn(familyBytes,Bytes.toBytes("q1"),i.toLong,Bytes.toBytes(i+"data_2"))
   }
   for(i<-0 to 200){
     put.addColumn(familyBytes,Bytes.toBytes("q2"),i.toLong,Bytes.toBytes(i+"data2"))
   }
   table.put(put)
  1. get数据。

  • get最新版本的数据:默认的方式即为取得最新版本的数据,这里不做描述。
  • get指定版本的数据:获取某一列
    主要用到的API:
    setTimeStamp(long timestamp)
    addColumn(byte [] family, byte [] qualifier)
    这里取的是timestamp为6下q1列的数据。

val table =new HTable(conf,tableName)
val get=new Get(Bytes.toBytes("row"))
get.setTimeStamp(6l)
get.addColumn(Bytes.toBytes("testFamily"),Bytes.toBytes("q1"))
val result=table.get(get)
val data=result.getValue(Bytes.toBytes("testFamily"),Bytes.toBytes("q1"))
println(Bytes.toString(data))
  • get指定版本的数据:获取某一列族该版本下的全部列数据
    在上一描述中,我们用addColumn获取的是某一列,下面我们获取某一列族下全部列的数据
    主要用到的API:
    setTimeStamp(long timestamp)
    addFamily(byte [] family)
    这里我们得到的是testFamily列族下q1以及q2timeStamp为6的两个数据,即我们可以获取某列族下特定版本的全部数据。

  • val table =new HTable(conf,tableName)
    val get=new Get(Bytes.toBytes("row"))
    get.setTimeStamp(6l)
    get.addFamily(Bytes.toBytes("testFamily"))
    val result=table.get(get)
  • get指定版本区间的数据:获取在指定时间戳区间内的数据

  • 主要用到的API:
    setTimeRange(long minStamp, long maxStamp)
    但是如果使用这个函数,并不能得到这个区间内的全部数据,它只会返回在这个区间内最新的版本的一个数据,(注意这里是左闭右开区间)如下:

    val table =new HTable(conf,tableName)
    val get=new Get(Bytes.toBytes("row"))
    get.setTimeRange(2l,300l)  //这样的话  得到的是在这个区间内最新的版本的数据
    get.addFamily(Bytes.toBytes(family))
    val result=table.get(get)
  • 这段代码虽然设置了timeRange是2-300,但是得到的是在这个区间内最新的版本的数据 。 结合API:
    setMaxVersions(int maxVersions).这个API是指定我们想要得到的数据的数量。比如如果我们想要得到最新50条数据,setMaxVersions(50)可以实现,该方法果不传参数则默认设置为Int.MaxValue。所以我们将这个两个API结合起来,就可以实现得到特定区间的全部数据。如下:

    val get=new Get(Bytes.toBytes("row"))
    get.setTimeRange(1l,50l)
    get.setMaxVersions(40)   //该函数设置返回版本的数目  如果不传参数  则设置为Int.MaxValue  传参数则返回对应参数的数目的数据
    //前面提到setTimeRange的作用,单独使用这个方法,得到的是在这个是在区域内最新的一条数据
    //但是如果setTimeRange和setMaxVersions配合起来使用,则可以达到取出一段时间戳内的数据。
    //如上面的例子,时间范围设置为[1,50),setMaxVersions设置为40,则会取出[1,50)最新的40条数据,即10-49
    //如果时间范围设置为[1,10),setMaxVersions设置为40,这个时候范围内的数不足40,则会将范围内的数全部取出
    get.addFamily(Bytes.toBytes(family))
    val result=table.get(get)   //
    val data=result.getValue(Bytes.toBytes(family),Bytes.toBytes("q1"))
    val data2=result.getValue(Bytes.toBytes(family),Bytes.toBytes("q2"))
    println(result.size())  //
    println(result.listCells().size())  //同result.size是一样的,cell的数目,即列的个数*返回版本的数目。
    val kv1: Cell =result.listCells().get(0)   //result中得到的cell数组,是先第一个列,再第二个列
    • get全部数据:前面我们提到了setMaxVersions(int maxVersions).这个API是指定我们想要得到的数据的数量。比如如果我们想要得到最新50条数据,setMaxVersions(50)可以实现,该方法果不传参数则默认设置为Int.MaxValue。所以当我们需要得到全部的数据时,可以指定maxVersions的值。这里不在做演示。

    其他问题说明:

    1. get数据时:
      前面提到,当我们使用setTimeRange(long minStamp, long maxStamp)和setMaxVersions(int maxVersions)可以得到指定数目的数据的数量,但是当一个列族下各个列的时间戳都不一样的时候会怎样呢?
      前面我们在put数据的时候,q1的时间戳为0-100,q2为0-200,我们设置时间戳的范围为[90,110):结果在代码中进行了说明。
      scala
      val table =new HTable(conf,tableName)
      val get=new Get(Bytes.toBytes("row"))
      get.setTimeRange(90l,110l)
      get.setMaxVersions(40) //如果有些世间戳版本,q1中存在,q2中不存在,比如现在q1是1-100,q2是1-200,设置范围[90,110)
      //则取出的数目为q1的90-100,共11个,q2的90-109,共20个,所以result.size()为31
      get.addFamily(Bytes.toBytes(family))
      val result=table.get(get)
    2. 当向同一个Rowkey的同一列下放入两个数据相同但是时间戳不同的数据,这两个数据会同时存在。但是如果时间戳是一样的,则数据会被重写。
    3. Result 的size方法: 返回的是cell的数目,即列的个数*返回版本的数目。
    4. 我们可以通过cell获取相关信息:
       val cell: Cell =result.listCells().get(0)
       System.out.println("RowName:"+new String(CellUtil.cloneRow(cell))+" ")
       System.out.println("Timetamp:"+cell.getTimestamp()+" ")
       System.out.println("column Family:"+new String(CellUtil.cloneFamily(cell))+" ")
       System.out.println("row Name:"+new String(CellUtil.cloneQualifier(cell))+" ")
       System.out.println("value:"+new String(CellUtil.cloneValue(cell))+" ")

你可能感兴趣的:(hbase,hbase,versions,timstamp,操作)