CDH 上 进行hbase bulkload

在从HIVE导入全量数据到HBASE的时候,我们使用SQL的方式是insert into table hbase_a select * from A.但是这种方式在17个数据节点上速度很慢,单表5亿数据需要50分钟,即便我们做了预分区。一共有五张表大表需要导入,时间难以忍受。

我们的ROWKEY都是做了MD5的,所以预分区很好分,我们17个REGION SERVER,分了17个区(我记得哪里推荐一个REGION SERVER 10个分区)。最终导入完毕后,检查分区数,远高于这个值。

后来发现HBASE全量导入有BULKLOAD这样的方法,性能很快。以后流程主要参考两篇文章:
1、https://cwiki.apache.org/confluence/display/Hive/HBaseBulkLoad
2、https://community.cloudera.com/t5/Storage-Random-Access-HDFS/HBase-slow-bulk-loading-using-Hive/td-p/43649

首先要在HIVE上进行配置,在hive辅助JAR目录,配置这个路径。我这里设置的路径为hive用户的home目录。

这个配置是针对HIVESERVER2的,如果你有多个HIVESERVER2实例,每个实例的目录文件需要一致的。配置这个目录后,就需要拷贝多个JAR包到对应的目录下:

sudo -u hdfs hdfs dfs -put -f /opt/cloudera/parcels/CDH/lib/hive/lib/hbase-client.jar /user/hive/
sudo -u hdfs hdfs dfs -put -f /opt/cloudera/parcels/CDH/lib/hive/lib/hbase-server.jar /user/hive/
sudo -u hdfs hdfs dfs -put -f /opt/cloudera/parcels/CDH/lib/hive/lib/hbase-common.jar /user/hive/
sudo -u hdfs hdfs dfs -put -f /opt/cloudera/parcels/CDH/lib/hive/lib/hbase-protocol.jar /user/hive/
sudo -u hdfs hdfs dfs -put -f /opt/cloudera/parcels/CDH/lib/hive/lib/hive-hbase-handler.jar /user/hive/
sudo -u hdfs hdfs dfs -put -f /opt/cloudera/parcels/CDH/lib/hive/lib/hbase-contrib.jar /user/hive/

赋权操作:

sudo -u hdfs hdfs dfs -chmod 554 /user/hive/.jar
sudo -u hdfs hdfs dfs -chown hive:hive /user/hive/.jar

下面这一大段操作,实际参考了HIVE的原始文章,大致流程:
1、建立存储HBASE分区键的表
2、从原始数据表中抽样出ROWKEY拆分键,它对原始数据进行排序,然后从排序中中找出对应的切分键,作为HBASE的ROWKEY SPLIT KEY。如果要生成17个分区,就要生成16个KEY.最后插入到前面建立的分区键表。

hdfs dfs -rm -r /tmp/hb_range_keys
hdfs dfs -mkdir /tmp/hb_range_keys

beeline -u “jdbc:hive2://” -e “CREATE EXTERNAL TABLE IF NOT EXISTS testzx.hb_range_keys(transaction_id_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/hb_range_keys’;”
beeline -u “jdbc:hive2://” -e ” create temporary function row_sequence as ‘org.apache.hadoop.hive.contrib.udf.UDFRowSequence’; INSERT OVERWRITE TABLE testzx.hb_range_keys SELECT a.id FROM ( SELECT row_sequence() as num, c.id FROM cust_app.app_cust_family c order by c.id) a WHERE ( a.num % ( round( ${total} / 12) ) ) = 0;”

将生成的分区键的数据文件,通过HDFS拷贝到hb_range_key_list目录。

hdfs dfs -rm -r /tmp/hb_range_key_list;
hdfs dfs -cp /tmp/hb_range_keys/* /tmp/hb_range_key_list;

注意:其实我在做这步骤的时候,没有成功。。。后来突然明白,我们的ROWKEY是MD5过后的,其实就是分区键本来就应该是既定的了。完全不需要去抽样出来!!根据这个思路,我直接将我做好的分区数据导入到前面的hb_range_keys表中,就完成了。关于HBASE如何针对字符串型的ROWKEY设计预分区键,可以参考下面:
1、https://hortonworks.com/blog/apache-hbase-region-splitting-and-merging/
2、https://grokbase.com/t/hbase/user/128xr5amhs/md5-hash-key-and-splits
3、http://hbase.apache.org/book.html#important_configurations
4、https://groups.google.com/forum/#!topic/nosql-databases/wQkYBAYRFF0

接下来建立导出HFILE表

hdfs dfs -rm -r /tmp/hbsort;
hdfs dfs -mkdir /tmp/hbsort;
beeline -u “jdbc:hive2://” -e “drop table testzx.hbsort; CREATE TABLE testzx.hbsort (id string,agent_code string,cust_ecif_id string,real_name string,gender string,birthday string,age string,certi_type string,certi_code string,job_id string,job_zh string,relatives_ecif_id string,relatives_real_name string,relatives_gender string,relatives_birthday string,relatives_age string,relatives_certi_type string,relatives_certi_code string,relatives_job_id string,relatives_job_zh string,relation string,policy_num string) STORED AS INPUTFORMAT ‘org.apache.hadoop.mapred.TextInputFormat’ OUTPUTFORMAT ‘org.apache.hadoop.hive.hbase.HiveHFileOutputFormat’ TBLPROPERTIES (‘hfile.family.path’ = ‘/tmp/hbsort/cf’);”

导入数据到导出HFILE表。主要设置的reduce task 数量要和前面设计的分区数多1.前面16个区,后面就应该17.


beeline -u “jdbc:hive2://” -e “set mapred.reduce.tasks=17;set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner;set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner; set mapreduce.totalorderpartitioner.path=/tmp/hb_range_key_list; set hfile.compression=gz; INSERT OVERWRITE TABLE testzx.hbsort select t.* from testzx.test_bulk_load t cluster by t.id;”

执行数据导入到HBASE

sudo -u hdfs hdfs dfs -chgrp -R hbase /tmp/hbsort
sudo -u hdfs hdfs dfs -chmod -R 775 /tmp/hbsort
#下面的环境需要导出,但是应该是SSH SESSION级别的,因为我设置这个变量后。
#CDH的好多变量和这个冲突了
export HADOOP_CLASSPATH=hbase classpath

#制定导入
hadoop jar /opt/cloudera/parcels/CDH/lib/hive/lib/hbase-server.jar completebulkload /tmp/hbsort test:test_bulk_load cf

至此完成。

发表评论

电子邮件地址不会被公开。 必填项已用*标注