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

HBase删除数据的更多相关文章

  1. HBase删除数据的原理

    转自:https://blog.csdn.net/cenjianteng/article/details/96645447 -------------------------------------- ...

  2. Hbase之批量删除数据

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...

  3. Hbase之删除数据

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...

  4. 实现HBase增量入库(HBase删除自定义时间戳行数据)

    目录 1. 背景描述 2. 问题描述 3. 解决方案 1. 背景描述 目前在做音乐推荐项目,前期做排序模型优化,任务是使用模型对用户的历史音乐进行排序,有6800多万个用户,约40G的用户数据,使用H ...

  5. 通过时间戳批量删除hbase的数据

    如何通过时间戳批量删除hbase的数据 我们使用hive关联hbase插入数据时,有时会写错数据,此时hbase中的数据量已经很大很大了(上亿).此时,我们要修改错误的数据,只需要删除写错的那部分数据 ...

  6. HBase按照行键范围删除数据

    #!/bin/bash #TOOL_PATH=$(cd "$(dirname "$0")"; pwd) #TOOL_PATH_TMP=$(cd "$( ...

  7. HBase按照TimeStamp删除数据

    #!/bin/bash #两种时间输入,一种是输入起始日期,另一种是直接输入hbase里面数据的起始时间戳 if [ $# != 5 ];then echo 'usage:sh byTimestamp ...

  8. 数据分页处理系列之二:HBase表数据分页处理

      HBase是Hadoop大数据生态技术圈中的一项关键技术,是一种用于分布式存储大数据的列式数据库,关于HBase更加详细的介绍和技术细节,朋友们可以在网络上进行搜寻,笔者本人在接下来的日子里也会写 ...

  9. Hbase写数据,存数据,读数据的详细过程

    Client写入 -> 存入MemStore,一直到MemStore满 -> Flush成一个StoreFile,直至增长到一定阈值 -> 出发Compact合并操作 -> 多 ...

随机推荐

  1. [原题复现+审计][ZJCTF 2019] WEB NiZhuanSiWei(反序列化、PHP伪协议、数组绕过)

    简介  原题复现:https://github.com/CTFTraining/zjctf_2019_final_web_nizhuansiwei/  考察知识点:反序列化.PHP伪协议.数组绕过   ...

  2. 金九银十想面BAT?那这些JDK 动态代理的面试点你一定要知道

    一.什么是代理 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UM ...

  3. 金九银十已到!掌握这300道java高频面试题,助你面试BAT无忧!

    前言 不知不觉已经到了九月了,回首看年初的时候简直像做梦一样.不得不说时间真的是无情一般的流逝,题外话就不多说了!回归正题,现在已经到了今年最后一波大好的跳槽涨薪的时机了,错过了这一次可能你就得等到明 ...

  4. 【flask-migrate】:ERROR [root] Error: Target database is not up to date.

    问题:flask-migrate数据迁移添加新的表,执行python manager.py db migrate 出现Target database is not up to date 原因: 1. ...

  5. LeetCode周赛#206

    1583. 统计不开心的朋友 #模拟 #暴力 题目链接 题意 有n为朋友,对每位朋友i,preference[i]包含 按亲密度从大到小 的朋友编号. 朋友们会被分为若干对,配对情况由pairs数组给 ...

  6. C语言基础知识:几种特殊的函数宏封装方式

    函数宏介绍 函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销. 函数宏本质上为宏,可以直接进行定义,例如: #define INT ...

  7. Codeforces Round #677 (Div. 3)

    F. Zero Remainder Sum || dp #include <cstdio> #include <algorithm> #include <cstring& ...

  8. 03_Service的绑定

    Start Service启动的Service,Application退出,Service也不会退出: Bind Service启动的Service,Application退出,Service就会退出 ...

  9. Django 2版本

    django2.0里面的path第一个参数不支持正则,你写什么就匹配,100%精准匹配 django2.0里面的re_path对应着django1.0里面的url 虽然django2.0里面的path ...

  10. rest-framework 解析器

    一 解析器的作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格 ...