• HBase删除数据


    hbase官方文档中描述了,hbase删除数据可以总结为下面三种(Java API有很多接口,可以总结下面的几种):

    1. 删除一个列的指定版本
    2. 删除一个列的所用版本
    3. 删除指定列族的所有列

    hbase删除数据,并不是马上删掉,只是对数据打一个删除标记,真正删除数据是等到下一次major_compact(除非KEEP_DELETED_CELLS=true)。当删除整行时,hbase会给这条数据每个列族打一个删除标记。有两个需要注意的地方:

    1. major_compact之前和之后,查询结果不一样,具体看例子:

    public class DeleteExample {
    
      public static void main(String[] args) throws IOException {
          
          Configuration conf = HBaseConfiguration.create();
          Connection connection = ConnectionFactory.createConnection(conf);
          
          Admin admin = connection.getAdmin();
          if(admin.tableExists(TableName.valueOf("test2"))){
              admin.disableTable(TableName.valueOf("test2"));
              admin.deleteTable(TableName.valueOf("test2"));
          }
    
          HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("test2"));
          HColumnDescriptor coldef = new HColumnDescriptor("cf");
          coldef.setMaxVersions(2);
          desc.addFamily(coldef);
          admin.createTable(desc);
          
          Table table = connection.getTable(TableName.valueOf("test2"));
          
          Put put1 = new Put(Bytes.toBytes("r1"));
          put1.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("c1"), 1, Bytes.toBytes("value1"));
          table.put(put1);
          
          Put put2 = new Put(Bytes.toBytes("r1"));
          put2.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("c1"), 2, Bytes.toBytes("value2"));
          table.put(put2);
          
          Put put3 = new Put(Bytes.toBytes("r1"));
          put3.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("c1"), 3, Bytes.toBytes("value3"));
          table.put(put3);
          
          //Delete delete = new Delete(Bytes.toBytes("r1"));
          //delete.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("c1"), 2);
          //table.delete(delete);
          
          
          table.close();
      }
    }

    上述代码中,创建了test2,并设置列族cf的最大版本数据2,然后先后添加了3个版本的单元格,这是从shell中可以查看数据,如下:

    hbase(main):035:0> get 'test2','r1',{COLUMN => 'cf:c1',VERSIONS => 2}
    COLUMN                  CELL                                                            
     cf:c1                  timestamp=3, value=value3                                       
     cf:c1                  timestamp=2, value=value2                                       

    然后,修改java代码,注释掉建表以及添加数据的代码,增加一个delete操作,指定版本时间戳为2(或者3),执行后,再从shell中查看数据,如下:

    hbase(main):033:0> get 'test2','r1',{COLUMN => 'cf:c1',VERSIONS => 2}
    COLUMN                  CELL                                                            
     cf:c1                  timestamp=3, value=value3                                       
     cf:c1                  timestamp=1, value=value1    

    可以发现,版本1复活了,这是由于服务器把内部处理推迟了,该列的老版本数据仍然存在,删除较新的版本(2)会使它们再次查询到。

    如果,在添加数据之后,做下flush和major_compact,然后再做删除操作,查询结果如下:

    hbase(main):036:0> flush 'test2'
    0 row(s) in 0.5280 seconds
    
    hbase(main):037:0> major_compact 'test2'
    0 row(s) in 0.3760 seconds
    
    hbase(main):038:0> get 'test2','r1',{COLUMN => 'cf:c1',VERSIONS => 2}
    COLUMN                  CELL                                                            
     cf:c1                  timestamp=3, value=value3                                       
    1 row(s) in 0.0100 seconds

    可以发现,版本1在合并之后,已经被删除了(因为这时已经有2个版本了,达到了设置的最大版本数据),之后再删除版本2,只能查询出版本3了

    另外,如果major_compact是在删除版本2之后做的,那么最后查询的数据仍然为版本1和版本3,我理解这是因为列族设置的最大版本数据为2,所以hbase会保留2个版本

    2.删除会屏蔽时间戳靠前的put操作,例子如下:

    hbase(main):047:0> create 'test6',{NAME=>'f1',VERSIONS=>3}
    0 row(s) in 1.2500 seconds
    
    => Hbase::Table - test6
    hbase(main):048:0> put 'test6','r1','f1:c','val',1
    0 row(s) in 0.0140 seconds
    
    hbase(main):049:0> put 'test6','r1','f1:c','val',3
    0 row(s) in 0.0080 seconds
    
    hbase(main):050:0> put 'test6','r1','f1:c','val',5
    0 row(s) in 0.0030 seconds
    
    hbase(main):051:0> get 'test6','r1',{COLUMN => 'f1:c',VERSIONS => 3}
    COLUMN                  CELL                                                            
     f1:c                   timestamp=5, value=val                                          
     f1:c                   timestamp=3, value=val                                          
     f1:c                   timestamp=1, value=val                                          
    3 row(s) in 0.0080 seconds
    
    hbase(main):052:0> delete 'test6','r1','f1:c',3
    0 row(s) in 0.0090 seconds
    
    hbase(main):053:0> get 'test6','r1',{COLUMN => 'f1:c',VERSIONS => 3}
    COLUMN                  CELL                                                            
     f1:c                   timestamp=5, value=val                                          
    1 row(s) in 0.0040 seconds
    
    hbase(main):054:0> put 'test6','r1','f1:c','val',2
    0 row(s) in 0.0100 seconds
    
    //get操作没有查询到版本2
    hbase(main):
    055:0> get 'test6','r1',{COLUMN => 'f1:c',VERSIONS => 3} COLUMN CELL f1:c timestamp=5, value=val 1 row(s) in 0.0080 seconds hbase(main):056:0> flush 'test6' 0 row(s) in 0.5280 seconds hbase(main):057:0> major_compact 'test6' 0 row(s) in 0.3280 seconds hbase(main):058:0> get 'test6','r1',{COLUMN => 'f1:c',VERSIONS => 3} COLUMN CELL f1:c timestamp=5, value=val 1 row(s) in 0.0070 seconds
    //做完major_compact之后,在PUT,可以查询对应的版本数据 hbase(main):
    059:0> put 'test6','r1','f1:c','val',2 0 row(s) in 0.0110 seconds hbase(main):060:0> get 'test6','r1',{COLUMN => 'f1:c',VERSIONS => 3} COLUMN CELL f1:c timestamp=5, value=val f1:c timestamp=2, value=val 2 row(s) in 0.0050 seconds

    在hbase shell中,指定时间戳T删除列时,会删除所有时间戳小于T的版本;

    java api中 :delete.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("c1"), 3),是只删除指定的版本

  • 相关阅读:
    Java日期时间差以及获取几天后或几天前
    java数组扩增的三种方式
    折半查找、冒泡排序和选择排序
    JavaSE-Map的三种循环
    Chrome浏览器showModalDialog兼容性及解决方案
    Integeter127与128
    statis代码块以及非static代码块之执行
    return、break、continue区别以及作用范围
    nodeJs + vue.js 小案例
    cordova CLI 命令
  • 原文地址:https://www.cnblogs.com/darange/p/9429931.html
Copyright © 2020-2023  润新知