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),是只刪除指定的版本


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM