基于hive的bulkload实践

1背景

工作中遇到需要将hive中数据同步到hbase的需求,之前是通过建设hive映射hbase表的方式,直接通过insert into table select * from table的方式写入的,刚开始的时候同步的表和业务数据量都比较小,数据同步速度可以接受。随着业务发展同步的表和数据量逐渐增多,同步一张表的时间越来越长。这种写入方式底层其实是调用hbase的put接口写入,大量数据写入的时候效率比较慢,而且影响hbase的请求数IO等,对线上业务造成影响。为了提高数据同步hbase的效率,后来我们改成了通过bulkload的方式将数据同步到hbase。

2HBaseBulkLoad方式

hbase bulkload方式有多种,

  • 编写mr程序生成hfile,然后通过hbase命令load数据

  • 通过hbase的ImportTsv工具生成hfile,然后通过命令load数据

  • 通过hive的方式生成hfile,然后通过hbase命令load数据

本文主要介绍hive的方式,下面让我们看看如何通过hive来生成hfile文件,然后加载到hbase。

3生成分区键

在生成hfile文件的时候是需要对数据进行排序的,为了启动多个reduce任务对数据进行并行排序,我们需要用分区键将数据按照rowkey字段将数据划分若干个大小相同的范围。这样做还有一个好处就是会生成多个hfile文件,当hbase加载文件的时候会分配到多个regionserver节点上,达到预分区的效果,提高后续数据读取和写入的速度。

首先我们需要创建一个表用于生成数据分割文件:

create external table test.hb_range_keys
(rowkey_range_start string) 
 row format serde 'org.apache.hadoop.hive.serde2.binarysortable.BinarySortableSerDe'
 stored as inputformat 'org.apache.hadoop.mapred.TextInputFormat' 
           outputformat 'org.apache.hadoop.hive.ql.io.HiveNullValueSequenceFileOutputFormat' 
 location '/tmp/hbase_splits/region5';--指定数据存储目录,接下来的步骤会用到

接下来需要根据数据rowkey字段对数据进行范围划分:

下面是hive官方文档给的一个示例方法,通过对0.01%的样本数据排序,然后选择每第910000行数据,将数据分为了12份,这里的假设是样本中的分布与表中的整体分布相匹配。 如果不是这种情况,则生成的分区键对数据范围划分不均衡导致并行排序时出现倾斜情况

select row_key from
(select row_key,row_sequence() as seq
from checkpoint.as_pintuan_pin_group --tprj_kucun
tablesample(bucket 1 out of 10000 on row_key) s
order by row_key
limit 10000000) x
where (seq % 910000)=0
order by row_key
limit 11;

如果对数据的分布情况比较了解的话可以直接执行分割键,例如我的数据的键值是从1累加自增的,我这里是将主键反转后作为rowkey的,所以我直接指定分区键将数据分为5份:

insert overwrite table test.hb_range_keys select c2 from (select concat_ws(",",'2','4','6','8') c1) t lateral view explode(split(c1,',')) num as c2 ;

4生成hfile文件

接下来就是生成hfile文件,首先再hive cli添加jar包设置相关参数:

--添加相关jar包
add jar hdfs://hdfs_url/user/hive/jar/hbase-common-1.2.4.jar;
add jar hdfs://hdfs_url/user/hive/jar/hive-hbase-handler-2.1.1.jar;
add jar hdfs://hdfs_url/user/hive/jar/hbase-server-1.2.4.jar;
add jar hdfs://hdfs_url/user/hive/jar/hbase-client-1.2.4.jar;
add jar hdfs://hdfs_url/user/hive/jar/hbase-protocol-1.2.4.jar;

set hive.execution.engine=mr;
set mapred.reduce.tasks=6;--分区数+1
set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner;
--指定上一步骤生成的分区键文件地址
set mapreduce.totalorderpartitioner.path=hdfs://HDFS80330/tmp/hbase_splits/region5/000000_0;
set hfile.compression=snappy;--指定snapp压缩

创建表用于生成保存hfile文件,'/tmp/hbsort1/info'路径中的info是列族名称,目前只支持单个列族

create table test.hbsort(
row_key            string,
column1            string,
column2            string,
column3            string,
column4            string
)
stored as
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHFileOutputFormat'
TBLPROPERTIES ('hfile.family.path' = '/tmp/hbsort/info');

 

接下来,将数据写入表中生成hfile文件:

insert overwrite table test.hbsort
select 
row_key,
column1,
column2,
column3,
column4 
from test_db.test_date
cluster by row_key;

 

5BulkLoad

最后一步,通过hbase工具将hfile加载到hbase,只需指定hfile地址和hbase的表名,根据指定表名自动创建hbase表

##执行shell命令
hadoop jar /usr/local/service/hbase/lib/hbase-server-1.2.4.jar completebulkload hdfs://hdfs_url/tmp/hbsort/ test:bulk_test

需要注意的是执行过程中可能会报缺少jar包和zookeeper连接失败的错误,需要将hbase相关jar和配置文件加到hadoop的class环境变量中。

##将hbase相关jar包加到环境变量中
export HADOOP_CLASSESPATH=/user/loacal/service/hbase/lib/* 

##将hbase配置文件加到hadoop环境中
hbase的hbase-site.xml文件添加到hadoop的etc配置文件夹中

 

更多文章请关注公众号:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值