Hive 大表数据导入 HBase

本文简单介绍 HBase 的数据导入工具 ImportTSV 。通过一次将 hive 大表导入 HBase 的实战案例,梳理期间遇到的问题,调研更优的导入方式。本文着重关注:

  • 如何借助 ImportTSV 工具将数据(文件:tsv、csv、hive 表) 导入 HBase,有哪些坑需要考虑?
  • HBase 如何建表,如何创建预分区?
  • Hive 数据导入 HBase 是否有其他方式,更有的方式?

1 ImportTSV 介绍

ImportTsv 是 HBase 提供的一个命令行工具,将存储在 HDFS 上的数据文件,通过指定的分隔符解析后,导入到 HBase 表中。(TSV :Tab-separated values)

这样的方式导入数据与正常写入流程不同的是,跳过了 WAL、Memcache 与 Flush 的过程,直接将 HFile 文件移动到 HBase 表空间目录下即可,不影响 RegionServer 的性能。

ImportTsv 提供两种导入的方式:

  1. 直接 MR 任务写入:这对小数据量,可以直接一行命令导入
  2. 先导出 hfile 再 bulkload:针对大数据量,高效导入

方案 1 :直接导入

首先创建 hbase 表:user (大表一定要预分区,不然全部会写到一个 region),然后执行命令导入:

hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:gender,info:age,info:idNumber,info:address,info:birthday user /tmp/user.txt
  • 指定分隔符为逗号
  • 指定导入的列:第一列为 HBASE_ROW_KEY,其他列都是 info列族下的name,gender,age,idNumber,address,birthday列
  • 指定需要导入的表名:user
  • 指定数据文件在HDFS上的目录地址:/tmp/user.txt

方案 2:hfile + bulkload

  1. 建 HBase 表(大表一定要预分区,不然全部会写到一个 region
  2. 生成 hfile
  3. bulkload
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.bulk.output=/louisvv/hfile_tmp -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:gender,info:age,info:idNumber,info:address,info:birthday user /yw/user.txt

2 实战案例

2.1 需求描述

Hive 表 42 亿行数据导入 HBase,采用上述提到的方案 2 : hfile + bulkload

Hive 表信息:
表名:hive_pub.dim_ip_cover_all_info_20220801_001
行数:42 亿
rowkey 为表第一个字段 ip_num,是 ip 转出的数值,保证唯一。

数据样例如下:
ip_num ip begin_ip end_ip country province_name city_name
1214810642 72.104.138.18 72.55.192.0 72.135.255.255 美国 美国
1214810654 72.104.138.30 72.55.192.0 72.135.255.255 美国 美国
137497864 8.50.13.8 8.47.158.0 8.127.255.255 美国 美国
137497876 8.50.13.20 8.47.158.0 8.127.255.255 美国 美国
137497888 8.50.13.32 8.47.158.0 8.127.255.255 美国 美国
137497900 8.50.13.44 8.47.158.0 8.127.255.255 美国 美国
137497912 8.50.13.56 8.47.158.0 8.127.255.255 美国 美国
137497924 8.50.13.68 8.47.158.0 8.127.255.255 美国 美国
3699562708 220.130.216.212 220.130.216.0 220.130.217.255 中国 台湾 彰化县
3699562720 220.130.216.224 220.130.216.0 220.130.217.255 中国 台湾 彰化县

2.2 实现方案

2.2.1 HBase 创建带预分区的表

这一步非常重要,hbase 建表如果不预分区,所有数据默认会写到一个分区,导入后需要长时间的 split ,compaction。 以下是我们的建表语句,指定压缩,预分区文件为手动生成的: /tmp/split.txt。

create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' },SPLITS_FILE => '/tmp/split.txt'

下面的重点的就是如何创建预分区,预分区的目的是让数据均衡分布在不同了 region - 分区。理解预分区需要理解 HBase rowkey 的字典排序,可以参考:[HBase] - 理解 HBase Rowkey 字典排序 - 简书

需要基于 rowkey 分布特征,划分分区,让数据均衡, hbase 提供三种预分区算法,注意DecimalStringSplit 算法 HBase 低版本1.4 以下不支持:

  • UniformSplit: rowkey 前缀完全随机
  • HexStringSplit: rowkey 是十六进制的字符串作为前缀的
  • DecimalStringSplit: rowkey 是 10 进制数字字符串作为前缀的,范围 0-9999999 (HBase 1.4 以下版本不支持)

了解 rowkey 特征,如果适用以上算法,可以直接采用这种方式建表。例如以下是创建一个 50 个 region 的表,采用 UniformSplit 分区算法。

create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' }, { NUMREGIONS => 50, SPLITALGO => 'UniformSplit' }

如果 rowkey 特征不适用于上述三种算法,需要自己生成分区区间,语法为:

# 直接指定
create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' }, SPLITS => ['10','20','30','40']

# 通过文件指定
create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' }, SPLITS_FILE => '/tmp/split.txt'

分析本案例:rowkey 的特点为:数值型,范围为:0-9999999,数据分布较为均衡。
数据行数:42亿,数据量 1.2 T。

根据数据分布,输出 split 分区文件如下,按照这个粒度,一共有 200+ 分区。这个可以通过手工或者脚本生成。

100|
105|
110|
115|
...
995|

具体分多少个分区,这个不一定需要绝对精准,可以大概估算,分区多,粒度细,分区少,粒度粗。 region个数估算,大致可以依据公示 :<region 个数> = <总数据量> / <单个region 的大小>(5-8G)来估算。

上述数据分粗一点,可以以1开头,2开头, 3开头, 4开头...9开头,一共 10 个分区。如果数据量大了 10 个分区可能太少。

1
2
3
4
5
6
7
8
9

一个 todo 疑问,是否有其他生成 splits 的方式,更优的方式?

2.2.2 导出 hive 数据

导出 hive 数据到 hdfs(字段逗号分隔)

2.2.3 生成 hfile

利用 importTsv 命令生成 hfile,需要指定列分隔符,HBASE_ROW_KEY 标识第一个字段为 rowkey,最后一个参数是数据文件的位置。

hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="|" \
-Dimporttsv.bulk.output=/data/hfile_tmp/ \
-Dimporttsv.columns=HBASE_ROW_KEY,cf:ip,cf:begin_ip,cf:end_ip,cf:country,cf:province_name,cf:city_name \
-Dmapreduce.map/reduce.memory.mb=5120 \
-Dmapreduce.map/reduce.java.opts=-Xmx4096m \
ns:xx /path/to/hdfs/tsvfile

2.2.4 bulkload 导入 HBase

bulkload 的实现原理可以参考之前的文章:HBase Bulkload 迁移数据及问题思考 - 简书
命令如下:

hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /path/to/hfile hbase_table

2.2.5 major compact

导入后执行一次 major compact 有助于提高数据本地化率, 合并小文件。操作建议在闲时执行。命令在 hbase shell 执行:

major_compact 'ns:table'

3 其他导入方式

上述流程稍显麻烦,是否还有其他更优的方式?

可以基于 Hive-HBase Integration 来导入 (https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration)。 步骤如下:

  1. 创建 HBase 表(同样注意创建预分区)

  2. 创建 hive 表 ,目的是为了生成 hfile,

需要注意,hive 下需要添加 HBase 相关的 jar:

add jar /lib/hive-hbase-handler-2.3.3.jar;
add jar /lib/hbase-protocol-1.1.1.jar;
add jar /lib/hbase-common-1.1.1.jar;
add jar /lib/hbase-client-1.1.1.jar;
add jar /lib/hbase-server-1.1.1.jar;

创建表:

create table stu_info{
  name string comment '名字',
  age int comment'年龄'
}
STORED AS
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHFileOutputFormat'
TBLPROPERTIES ('hfile.family.path' = '/user/hive-hbase/info');

输出格式一定要为:HiveHFileOutputFormat。/user/hive-hbase/info 是生成的 hfile 在 HDFS 上的路径,其中 info 为 Hbase 的 family。

  1. 导入数据到 Hive 表:生成 hfile
insert overwrite table stu_info select  xxx from xxx

到 hfile.family.path 目录查看生成的 hfile

  1. bulkload hfile 到 hbase 表
bin/hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /user/hive-hbase/info/ hbase_table

参考致謝
使用ImportTSV向HBase中导入数据 | LouisvV's Blog
hive表数据导入到Hbase - CodeAntenna
Creating HBase HFiles From a Hive Table - Cloudera Community - 244627
理解 HBase Rowkey 字典排序 - 简书
HBase Bulkload 迁移数据及问题思考 - 简书

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容