今天主要来说一下Hbase怎么批量删除数据,我们都知道Hbase是一个Nosql的分布式存储数据引擎,它可以支持千万级别的QPS写入,但是有时候我们需要批量的删除他的数据,今天就来介绍两种方法:
1.首先我们想到的就是TTL,TTL即Time To Live的缩写,顾名思义就是生存期的意思。TTL设置了一个基于时间戳的临界值, 内部的管理会自动检查TTL值是否达到上限,在major合并过程中时间戳被判定为超过TTL的数据会被自动删除。
实际上就是判断:currentMilliseconds - ts > 你设定的时间,如果满足,数据就失效了。
TTL参数的单位是秒,默认值是Integer.MAX_VALUE,即2^31-1=2 147 483 647 秒,大约68年。使用TTL默认值的数据可以理解为永久保存。
(1).disable 'test'(第一步一定要先禁用这张表)
(2).alter 'test',{NAME=>'f1',TTL=>'86400'}(单位是秒,即过期时间为1天)
(3).enable 'test'(在启用这张表,如果数据比较多一定等他启动完成,然后在进行其他操作)
但是这样有一个问题,就是TTL只能控制超过一定的时间就让其过期,但是不能实现一段时间内的数据,比如我们要删除10号到13号的数据,这个TTL是实现不了的,那怎么办呢?别急接着往下看.
2.我们可以利用Hbase的API先scan一定时间戳范围内的数据,然后在批量的删除,具体实现的代码如下:
package hbase
import java.util
import kafka.PropertiesScalaUtils
import org.apache.hadoop.hbase.{HBaseConfiguration, TableName}
import org.apache.hadoop.hbase.client._
/**
* 根据时间戳范围删除hbase的数据;
*/
object HbaseUtil {
def main(args: Array[String]): Unit = {
val s = System.currentTimeMillis()
val conf = HBaseConfiguration.create()
conf.set("hbase.zookeeper.quorum", PropertiesScalaUtils.loadProperties("zk_hbase")) //zk的地址;
conf.set("hbase.zookeeper.property.clientPort", PropertiesScalaUtils.loadProperties("zk_port"))
conf.set("hbase.master", PropertiesScalaUtils.loadProperties("hbase_master"))
conf.set("hbase.defaults.for.version.skip", "true")
conf.set("hhbase.rootdir", PropertiesScalaUtils.loadProperties("hbase_rootdir"))
conf.set("zookeeper.znode.parent", PropertiesScalaUtils.loadProperties("zookeeper_znode_parent"))
val connection = ConnectionFactory.createConnection(conf)
val table = connection.getTable(TableName.valueOf(PropertiesScalaUtils.loadProperties("hbase_table")))
val scan = new Scan()
scan.setTimeRange(args(0).toLong,args(1).toLong)
val rs = table.getScanner(scan)
val it = rs.iterator()
val list = new util.ArrayList[Delete]()
while (it.hasNext){
val delete = it.next()
val d = new Delete(delete.getRow)
list.add(d)
}
if(list.size()>0){
println("一共有多少条数据:"+list.size())
println("开始删除--------------------")
table.delete(list)
println("删除完成--------------------")
}else{
println("没有数据--------------------")
}
table.close()
connection.close()
val e = System.currentTimeMillis()
println("总共用时:"+ (e-s) +"毫秒")
}
}
这么写虽然能实现对指定时间戳范围内的数据进行删除,但是这么写就没有问题吗,是有问题的,这样删除的效率是非常低的,因为需要先把需要删除的查出来放到一个list里面,然后在进行批量的删除,这个方法对于数据量小的时候是可以的,数据量大的话,就会非常的慢,一定要根据自己的实际情况而定