马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 168主编 于 2019-12-2 10:28 编辑
作者:无尴尬不青春 来源:大数据极客
1背景
工作中遇到需要将hive中数据同步到hbase的需求,之前是通过建设hive映射hbase表的方式,直接通过insert into table select * from table的方式写入的,刚开始的时候同步的表和业务数据量都比较小,数据同步速度可以接受。随着业务发展同步的表和数据量逐渐增多,同步一张表的时间越来越长。这种写入方式底层其实是调用hbase的put接口写入,大量数据写入的时候效率比较慢,而且影响hbase的请求数IO等,对线上业务造成影响。为了提高数据同步hbase的效率,后来我们改成了通过bulkload的方式将数据同步到hbase。
2 HBaseBulkLoad方式
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节点上,达到预分区的效果,提高后续数据读取和写入的速度。 首先我们需要创建一个表用于生成数据分割文件:
[AppleScript] 纯文本查看 复制代码 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份,这里的假设是样本中的分布与表中的整体分布相匹配。如果不是这种情况,则生成的分区键对数据范围划分不均衡导致并行排序时出现倾斜情况
[AppleScript] 纯文本查看 复制代码 add jar hdfs://hdfs_url/user/hive/jar/hive-contrib-2.1.1.jar; create temporary function row_sequence as 'org.apache.hadoop.hive.contrib.udf.UDFRowSequence'; select row_key from ( select row_key,row_sequence() as seq from test_db.test_data_table 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份:
[AppleScript] 纯文本查看 复制代码 insert overwrite table test.hb_range_keys select c2 from (select concat_ws(",",'2','4','6','8') c1) tlateral view explode(split(c1,',')) num as c2 ;
4生成hfile文件
接下来就是生成hfile文件,首先再hive cli添加jar包设置相关参数:
[AppleScript] 纯文本查看 复制代码
--添加相关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;
--reduce数为分区数+1
set mapred.reduce.tasks=6;
set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner;
--指定上一步骤生成的分区键文件地址
set mapreduce.totalorderpartitioner.path=hdfs://hdfs_url/tmp/hbase_splits/region5/000000_0;
set hfile.compression=snappy;--指定snapp压缩
创建表用于生成保存hfile文件,'/tmp/hbsort1/info'路径中的info是列族名称,目前只支持单个列族
[AppleScript] 纯文本查看 复制代码
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文件:
[AppleScript] 纯文本查看 复制代码
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表
[AppleScript] 纯文本查看 复制代码
##执行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环境变量中。
[AppleScript] 纯文本查看 复制代码
##将hbase相关jar包加到环境变量中
export HADOOP_CLASSESPATH=/user/loacal/service/hbase/lib/*
##将hbase配置文件加到hadoop环境中
hbase的hbase-site.xml文件添加到hadoop的etc配置文件夹中
|