hbase 批量导入数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wenzhou1219/article/details/88524589

Bulk Loading

向hbase写入数据常用两种方式:

  • 客户端 API写入
  • Mapreduce任务TableOutputFormat格式输出

然而,对于超大量的数据写入,这两种方式都不合适,会非常占用内存和耗时而且JVM GC和Hbase compaction都会急剧增加。为此,Hbase提供了另一种很好的解决方式——Bulk Loading,顾名思义就是批量导入,它通过预生成Hbase存储格式文件Hfile然后直接拷贝到对应RegionServer的方式减少导入时间和集群性能损耗。

包括如下几步:

  • 从数据库或其他源抽取待写入数据,写入HBase所在HDFS集群
  • 数据预生成为HFile文件,注意生成的HFile文件和导入HDFS的文件差不多大,主要保证集群空间足够大
  • 导入数据到HBase

后两步又分为不同场景处理:

  • 对于Hbase列不变的表,可以使用预定义工具importtsv来完成整个过程
  • 但是对于列一直在动态变化的表,必须自己写MR程序来完成整个过程

Importtsv

使用importtsv工具生成HFile必须保证导入HDFS的文件内容格式为tsv,也就是每行内容是使用相同分隔符分割的同字段数的内容,第一字段对应row key,后面每列对应hbase表的一字段(Qualifier),类似如下:

row1^v11^v12^v13
row2^v21^v22^v23
row3^v31^v32^v33

生成HFile

首先,如下生成HFile,参数表示从HDFS处$input读入数据到表$table中,数据以^分割,对应的数据表字段名为依次为c1、c2、c3,生成的HFile保存在$output处。

${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.4.4.jar importtsv \
        -Dimporttsv.columns=HBASE_ROW_KEY,b:c1,b:c2,b:c3 \
		-Dimporttsv.separator=^ \
        -Dimporttsv.bulk.output=$output \
        $table $input \
        >> $log_file 2>&1

导入HBase

然后,如下将生成的HFile导入Hbase 表$table中。

${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.4.4.jar completebulkload $output $table >> log/${table}-load.log 2>&1

自定义MR

使用importtsv固然很好,但是如果导入的数据列名是动态变化的,比如如下每行数据对应的hbase 字段名和个数都不一样,这种情况就没法用importtsv来处理,需要自己写MR来处理生成HFile和加载到HBase。

row1 (k1,v11) (k2,v12)
row2 (k2,v22) (k3,v23) (k4,v24)
row3 (k3,v31)

生成HFile

这种情况需要自行考虑MR的输入,因为具体每列数据对应的字段名到底是什么,是没办法像importtsv一样提前指定的,因此必须在输入数据中包含此信息,比如如下,用|分别分割行键、字段名列表、对应值列表。

row1|k1^k2|v11^v22
row2|k2^k3^k4|v22^c23^v24
row3|k3|v31
  • 设定格式

这里为了生成HFile格式,MR的输入输出和中间map结果设置如下,最终生成文件格式为HFileOutputFormat2。

job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(HFileOutputFormat2.class);

job.setMapOutputKeyClass(ImmutableBytesWritable.class);
job.setMapOutputValueClass(Put.class);
  • 设定 Mapper

任务的Mapper部分主要完成读入并拆分数据,生成指定格式中间文件即可,如下,按照之前说的数据输入,先按照|拆分出三部分,按照rowKey,colKey和colVal填入put中写入文件即可,这里的列族COL_FAMILY是强制指定的。

	public void map(LongWritable key, Text value, Mapper<LongWritable, Text, ImmutableBytesWritable, Put>.Context context) throws IOException, InterruptedException {
		String line = value.toString();
        String[] list = line.split("\\|", -1);
        long length = list.length;

        //每行数据输入格式为rowkey|c1^c2^c3|v1^v2^v3
        if( length != 3 || list[1].isEmpty() || list[2].isEmpty()) {
            return;
        }

        String Rowkey=list[0];

        String[] colKey = list[1].split("\\^", -1);
        String[] colVal = list[2].split("\\^", -1);
        if (colKey.length!=colVal.length){
            return;
        }

        long colLen = colKey.length;

        //拼装rowkey和put
        ImmutableBytesWritable PutRowkey=new ImmutableBytesWritable(Rowkey.getBytes());
        Put put=new Put(Rowkey.getBytes());

        for (int i= 0; i<colLen; i++){
            if (!colVal[i].isEmpty()){
                put.addColumn(COL_FAMILY.getBytes(), colKey[i].getBytes(), colVal[i].getBytes());
            }
        }

        context.write(PutRowkey, put);
    }
  • 设定Reducer

任务的Reducer不用自己指定,如下HFileOutputFormat2.configureIncrementalLoad会根据hbase对应表信息设置reducer和对应的reducer 个数。

//配置MapReduce作业,以执行增量加载到给定表中
Configuration hbaseConf=HBaseConfiguration.create();
hbaseConf.addResource(new Path("/home/wenzhou/hbase/conf/hbase-site.xml"));

Connection conn=ConnectionFactory.createConnection(hbaseConf);
Table table=conn.getTable(TableName.valueOf(tname));
Admin admin=conn.getAdmin();

HFileOutputFormat2.configureIncrementalLoad(job, table, conn.getRegionLocator(TableName.valueOf(tname)));

导入HBase

确认上述数据生成成功后,如下即可加载到hbase表中。

//生成的HFile Bulkload导入
LoadIncrementalHFiles loader = new LoadIncrementalHFiles(hbaseConf);
loader.doBulkLoad(new Path(outputReal), admin, table, conn.getRegionLocator(TableName.valueOf(tname)));

注意事项

  • 实际reducer个数和表的region个数相同,大量数据首次导入必须预分区,否则默认只有一个redion对应一个reducer,很容易Mem Overflow且数据倾斜厉害导致耗时很长

源码下载

对应源码下载链接,可直接用于生产环境

开发参考文档

原创,转载请注明来自

猜你喜欢

转载自blog.csdn.net/wenzhou1219/article/details/88524589