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))+" ")
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: HBase是一个分布式的、面向列的NoSQL数据库,它是建立在Hadoop之上的。使用Java操作HBase可以通过HBase提供的Java API来实现。Java API提供了一系列的类和接口,可以用来连接HBase集群、创建表、插入数据、查询数据等操作。具体的操作步骤如下: 1. 引入HBase的Java API依赖包,可以通过Maven或手动下载方式获取。 2. 创建HBase的配置对象,设置HBase集群的Zookeeper地址和端口号。 3. 创建HBase的连接对象,通过配置对象和连接对象来连接HBase集群。 4. 创建HBase表,通过HBaseAdmin类的createTable方法来创建表。 5. 插入数据,通过Put类来封装数据,然后通过Table类的put方法来插入数据。 6. 查询数据,通过Get类来封装查询条件,然后通过Table类的get方法来查询数据。 7. 删除数据,通过Delete类来封装删除条件,然后通过Table类的delete方法来删除数据。 8. 关闭连接,通过Connection类的close方法来关闭连接。 以上就是使用Java操作HBase的基本步骤,需要注意的是,在使用HBase时需要考虑数据的一致性和可靠性,同时需要合理设计表结构和数据存储方式。 ### 回答2: HBase是一种分布式的非关系型数据库,它被广泛应用于大规模数据存储和数据分析领域。HBase的特点在于高可靠性、高可扩展性、分布式计算能力强等优点,可以很好地处理海量数据。 HBase的开发语言支持Java、Python等多种语言,使用Java操作HBase时,需要使用HBase提供的Java API,通过Java编写代码来实现对HBase操作操作HBase可以分为连接HBase、创建表、插入数据、查询数据、删除数据、关闭连接等步骤。 1. 连接HBase 通过使用HBase提供的Configuration类,可以设置连接HBase所需的配置信息,包括zk连接地址、端口号等。创建完Configuration对象后,通过ConnectionFactory来获取连接HBase的Connection对象。 Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "192.168.1.100"); conf.set("hbase.zookeeper.property.clientPort", "2181"); Connection conn = ConnectionFactory.createConnection(conf); 2. 创建表 通过Connection对象,可以使用Admin来操作HBase,创建表需要先创建TableDescriptor和ColumnFamilyDescriptor对象,然后通过Admin.createTable()方法来创建表。 Admin admin = conn.getAdmin(); TableName tableName = TableName.valueOf("test_table"); TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName); ColumnFamilyDescriptor columnFamilyDescriptor = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("test_family")).build(); TableDescriptor tableDescriptor = tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor).build(); admin.createTable(tableDescriptor); admin.close(); 3. 插入数据 插入数据需要先创建Put对象,并将需要插入的数据通过AddColumn()方法添加到Put对象中,然后通过Table.put()方法将数据插入到表中。 Table table = conn.getTable(tableName); Put put = new Put(Bytes.toBytes("row_key")); put.addColumn(Bytes.toBytes("test_family"), Bytes.toBytes("test_qualifier"), Bytes.toBytes("test_value")); table.put(put); table.close(); 4. 查询数据 查询数据需要先创建Get对象,然后通过Table.get()方法来获取数据。可以通过addColumn()方法指定需要获取的列。 Get get = new Get(Bytes.toBytes("row_key")); get.addColumn(Bytes.toBytes("test_family"), Bytes.toBytes("test_qualifier")); Result result = table.get(get); byte[] resultValue = result.getValue(Bytes.toBytes("test_family"), Bytes.toBytes("test_qualifier")); 5. 删除数据 删除数据需要先创建Delete对象,指定需要删除的行和列,然后通过Table.delete()方法来执行删除操作。 Delete delete = new Delete(Bytes.toBytes("row_key")); delete.addColumn(Bytes.toBytes("test_family"), Bytes.toBytes("test_qualifier")); table.delete(delete); 6. 关闭连接 操作HBase后需要关闭连接以释放资源。 table.close(); admin.close(); conn.close(); 综上所述,使用Java操作HBase需要掌握HBase的Java API以及相关的操作步骤。通过以上代码示例,可以更好地理解Java在HBase中的应用。 ### 回答3: HBase是Apache Hadoop生态系统中的一种面向列的数据库系统,它能够提供低延迟的实时读写能力以及可扩展性和容错性。Java作为一种流行的编程语言,可以被用来操作HBase数据库系统。下面是使用Java操作HBase的一些常见操作和案例。 1. 连接HBase:在Java中,我们可以使用HBaseConfiguration类来创建连接HBase的配置信息。使用HBaseAdmin类可以验证HBase数据库是否可用,如下所示: ``` Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "localhost"); HBaseAdmin admin = new HBaseAdmin(conf); boolean availability = admin.isMasterRunning(); ``` 2. 创建表格:可以使用HTableDescriptor和HColumnDescriptor类来创建HBase表格: ``` Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "localhost"); HBaseAdmin admin = new HBaseAdmin(conf); HTableDescriptor tableDesc = new HTableDescriptor("mytable"); HColumnDescriptor familyDesc = new HColumnDescriptor("myfamily"); tableDesc.addFamily(familyDesc); admin.createTable(tableDesc); ``` 3. 插入数据:HBase的数据是基于行和列族的,可以使用Put类来将数据插入HBase的表中。可以使用HBase shell中的put命令来插入数据,而Java代码如下: ``` Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "localhost"); HTable table = new HTable(conf, "mytable"); Put put = new Put(Bytes.toBytes("row1")); put.add(Bytes.toBytes("myfamily"), Bytes.toBytes("mycolumn"), Bytes.toBytes("myvalue")); table.put(put); ``` 4. 查询数据:HBase提供了多种查询方式,如Get、Scan和Filter等。使用Get查询可以根据行键来查询指定行的数据,如下所示: ``` Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "localhost"); HTable table = new HTable(conf, "mytable"); Get get = new Get(Bytes.toBytes("row1")); Result result = table.get(get); byte[] value = result.getValue(Bytes.toBytes("myfamily"), Bytes.toBytes("mycolumn")); ``` 5. 删除数据:可以使用Delete类来删除指定的行或列族,如下所示: ``` Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "localhost"); HTable table = new HTable(conf, "mytable"); Delete delete = new Delete(Bytes.toBytes("row1")); delete.deleteColumn(Bytes.toBytes("myfamily"), Bytes.toBytes("mycolumn")); table.delete(delete); ``` 综上所述,以上是使用Java操作HBase的一些基本操作和案例,HBase的Java API提供了许多高级功能,包括复杂的过滤查询、多版本控制和扫描器等,使其成为处理大量数据的优秀工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值