IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Hbase如何批量删除指定数据 -> 正文阅读

[大数据]Hbase如何批量删除指定数据

一、背景:

  Hbase是一个列式存储,nosql类型的数据库,类似mongodb。

????????我们都知道Hbase是一个Nosql的分布式存储数据引擎,它可以支持千万级别的QPS写入,但是有时候我们需要批量的删除他的数据,?目前似乎没有提供批量删除的方法,只有一个单行删除的命令:deleteall 'tablename', rowkey

二、删除方法:

  方法一:通过写 shell 脚本,从 hbase shell 查出需要删除的 rowkey ,拼成删除命令(deleteall 'tablename', rowkey),写到文本 del_temp.txt ;然后执行 hbase shell del_temp.txt?

  方法二:通过建映射表,比如在 hive 建一个映射表,然后写 hql?查出需要删除的 rowkey ,拼成删除命令(deleteall 'tablename', rowkey),写到文本 del_temp.txt?;然后执行?hbase shell del_temp.txt?

  方法三:通过python/ java 代码,调用 hbase 的单行删除方法,写个循环删除?

  方法四:通过建映射表,比如在 hive 建一个映射表,将?需要保留的数据?通过 hql 查询出来,备份到 hive 的一张临时表 ;然后 在hbase shell 里面 执行 truncate 'tablename' ,清空 hbase 的数据; 最后 在将数据 从 hive 的备份表 读出来,插入 映射表,写回 hbase;

  总结:

  前面3种方法,本质上都是在 hbase 中逐行删除;而第4种方法,是利用hive的map reduce倒数据。对于不熟悉 hbase 和 java 语法的开发人员而言,使用2/4方法,是灵活性最好的。

第二种删除方法为例:

  1、hive 建映射表:

CREATE EXTERNAL TABLE edw.test_turboway_hbase(
  `keyid` string COMMENT 'from deserializer',
  `title` string COMMENT 'from deserializer',
  `bizdate` string COMMENT 'from deserializer',
  `loginid` string COMMENT 'from deserializer')
ROW FORMAT SERDE
  'org.apache.hadoop.hive.hbase.HBaseSerDe'
STORED BY
  'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
  'hbase.columns.mapping'=':key,cf:title,cf:bizdate,cf:loginid',
  'serialization.format'='1')
TBLPROPERTIES (
  'COLUMN_STATS_ACCURATE'='false',
  'hbase.table.name'='test_turboway',
  'numFiles'='0',
  'numRows'='-1',
  'rawDataSize'='-1',
  'totalSize'='0',
  'transient_lastDdlTime'='1543297130')

  2、记录hive查询要删除的数据,拼成命令:

hive -e 
"select concat('deleteall \'test_turboway\',\'',keyid,'\'') 
from edw.test_turboway_hbase 
where loginid = '20181122'"
 > del_temp.txt && echo 'exit' >> del_temp.txt

  3、hbase shell?执行删除命令

hbase shell del_temp.txt > del.log

二、

? ?由于从kafka消费过来写入hbase的数据量有点大,导致关联的外部hive表使用性能有点差,因此决定把已经导入hive的dwd层后的数据进行删除,删除脚本如下:

del_date=$1
filename=$(pwd)/rowkey.csv

beeline ?
--incremental=true
--showHeader=false
--outputformat=dsv
--delimiterForDSV=$'\t' ?
-e
"select ?concat('deleteall \'default:monitorData\',\'',row_key,'\'') ?
from ?dw_ods.ods_api_msp_plan_point
where row_key like '%${del_date}'
">${filename}

sed -i '$d' ${filename}
hbase shell ${filename} > del.log


????????以上脚本删除的逻辑是首先通过外部关联表查询出需要删除的rowkey,由于这个表的rowkey后缀是日期,因此通过模糊日期查询出需要删除的rowkey写入一个文件,由于写入文件后最后一行是无关的信息,因此这里需要用sed命令进行删除。

79ba3df3493780ee65c5dcddf91b84fd.png

????????脚本编辑好后,写入del_hbase.sh文件,最后执行sh del_hbase.sh yyyyMMdd进行删除指定日期的数据?

三、方法三:比如我们要删除10号到13号的数据

我们可以利用Hbase的API先scan一定时间戳范围内的数据,然后在批量的删除,具体实现的代码如下:

 /**
  * 根据时间戳范围删除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里面,然后在进行批量的删除,这个方法对于数据量小的时候是可以的,数据量大的话,就会非常的慢,一定要根据自己的实际情况而定

这两种方法还是推荐使用第一张设置TTL,让其自动过期,如果非要删除段时间范围内的,可以用第二种但是要考虑性能问题.
————————————————
?

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:00:29  更:2021-09-01 12:01:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:10:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码