Hbase 批量数据BulkLoad 导入使用



以下主要介绍BulkLoad导入数据到hbase 中


HBase有多种导入数据的方法,最直接的方法就是在MapReduce作业中使用TableOutputFormat作为输出,或者使用标准的客户端API,
但是这些都不是非常有效的方法。 
Bulkload利用MapReduce作业输出HBase内部数据格式的表数据,
然后将生成的StoreFiles直接导入到集群中。与使用HBase API相比,
使用Bulkload导入数据占用更少的CPU和网络资源。 所以在做大量数据导入到hbase时优先考虑使用bulkLoad




Bulkload过程主要包括三部分: 


1.从数据源(通常是文本文件或其他的数据库)提取数据并上传到HDFS 
这一步不在HBase的考虑范围内,不管数据源是什么,只要在进行下一步之前将数据上传到HDFS即可。 


2.利用一个MapReduce作业准备数据 
这一步需要一个MapReduce作业,并且大多数情况下还需要我们自己编写Map函数,而Reduce函数不需要我们考虑,
由HBase提供。该作业需要使用rowkey(行键)作为输出Key,KeyValue、Put或者Delete作为输出Value。
MapReduce作业需要使用HFileOutputFormat2来生成HBase数据文件。为了有效的导入数据
,需要配置HFileOutputFormat2使得每一个输出文件都在一个合适的区域中。为了达到这个目的,
MapReduce作业会使用Hadoop的TotalOrderPartitioner类根据表的key值将输出分割开来。
HFileOutputFormat2的方法configureIncrementalLoad()会自动的完成上面的工作。 


3.告诉RegionServers数据的位置并导入数据 
这一步是最简单的,通常需要使用LoadIncrementalHFiles(更为人所熟知是completebulkload工具),将文件在HDFS上的位置传递给它,
它就会利用RegionServer将数据导入到相应的区域。






package com.ww.hbase.bulkimport;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.HTable;
//import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;


public class BulkLoadDriver extends Configured implements Tool{



private static final String DATA_SEPERATOR = "\\s+";
    private static final String TABLE_NAME = "user";//表名
    private static final String COLUMN_FAMILY_1="info";//列组1
    private static final String COLUMN_FAMILY_2="data";//列组2


    public static void main(String[] args) {
        try {
            int response = ToolRunner.run(HBaseConfiguration.create(), new BulkLoadDriver(), args);
            if(response == 0) {
                System.out.println("Job is successfully completed...");
            } else {
                System.out.println("Job failed...");
            }
        } catch(Exception exception) {
            exception.printStackTrace();
        }
    }


    
    public int run(String[] args) throws Exception {
        String outputPath = args[1];
        /**
         * 设置作业参数
         */
        Configuration configuration = new Configuration();
        configuration.set("data.seperator", DATA_SEPERATOR);
        configuration.set("hbase.table.name", TABLE_NAME);
        configuration.set("COLUMN_FAMILY_1", COLUMN_FAMILY_1);
        configuration.set("COLUMN_FAMILY_2", COLUMN_FAMILY_2);
        Job job = Job.getInstance(configuration, "Bulk Loading HBase Table::" + TABLE_NAME);
        job.setJarByClass(BulkLoadDriver.class);
        job.setInputFormatClass(TextInputFormat.class);
        job.setMapOutputKeyClass(ImmutableBytesWritable.class);//指定输出键类
        job.setMapOutputValueClass(Put.class);//指定输出值类
        job.setMapperClass(BulkLoadMapper.class);//指定Map函数
        FileInputFormat.addInputPaths(job, args[0]);//输入路径
        FileSystem fs = FileSystem.get(configuration);
        Path output = new Path(outputPath);
        if (fs.exists(output)) {
            fs.delete(output, true);//如果输出路径存在,就将其删除
        }
        
        FileOutputFormat.setOutputPath(job, output);//输出路径
        TableName tableName = TableName.valueOf(TABLE_NAME);
        
HFileOutputFormat2.configureIncrementalLoad(job, new HTable(configuration,tableName));
        job.waitForCompletion(true);
        if (job.isSuccessful()){
            HFileLoader.doBulkLoad(outputPath, TABLE_NAME);//导入数据
            return 0;
        } else {
            return 1;
        }
    }






}








package com.ww.hbase.bulkimport;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;


/**
 * Created by wwei 2016-3-3.
 */
public class BulkLoadMapper extends Mapper<LongWritable, Text, ImmutableBytesWritable, Put> {
    private String dataSeperator;
    private String columnFamily1;
    private String columnFamily2;


    public void setup(Context context) {
        Configuration configuration = context.getConfiguration();//获取作业参数
        hbaseTable = configuration.get("hbase.table.name");
        dataSeperator = configuration.get("data.seperator");
        columnFamily1 = configuration.get("COLUMN_FAMILY_1");
        columnFamily2 = configuration.get("COLUMN_FAMILY_2");
    }


    public void map(LongWritable key, Text value, Context context){
        try {
            String[] values = value.toString().split(dataSeperator);
            if(values != null && values.length == 5){
            ImmutableBytesWritable rowKey = new ImmutableBytesWritable(values[0].getBytes());
                Put put = new Put(Bytes.toBytes(values[0]));
                put.add(Bytes.toBytes(columnFamily1), Bytes.toBytes("name"), Bytes.toBytes(values[1]));
                put.add(Bytes.toBytes(columnFamily1), Bytes.toBytes("gender"), Bytes.toBytes(values[2]));
                
                put.add(Bytes.toBytes(columnFamily2), Bytes.toBytes("height" ), Bytes.toBytes(values[3]));
                put.add(Bytes.toBytes(columnFamily2), Bytes.toBytes("weight"), Bytes.toBytes(values[4]));
                /*for (int i = 3; i < values.length; ++i){
                    put.add(Bytes.toBytes(columnFamily2), Bytes.toBytes("hour : " + i), Bytes.toBytes(values[i]));
                }*/
                context.write(rowKey, put);
            }
            
            
        } catch(Exception exception) {
            exception.printStackTrace();
        }


    }


}






package com.ww.hbase.bulkimport;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;


/**
 * Created by wwei 2016-3-3
 */
public class HFileLoader {
    public static void doBulkLoad(String pathToHFile, String tableName){
        try {
            Configuration configuration = new Configuration();
            HBaseConfiguration.addHbaseResources(configuration);
            LoadIncrementalHFiles loadFfiles = new LoadIncrementalHFiles(configuration);
            HTable hTable = new HTable(configuration, tableName);//指定表名
            loadFfiles.doBulkLoad(new Path(pathToHFile), hTable);//导入数据
            System.out.println("Bulk Load Completed..");
        } catch(Exception exception) {
            exception.printStackTrace();
        }


    }


}






将类打包为:bulkimport.jar


在集群上执行:
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar bulkimport.jar /data/test.txt /data/outtest


注意:这里用这个将Hbase需要的jar包加载到classpath 环境中,否则执行会抱NoClassFoundException 异常。

在执行这之前,先创建好Hbase对应的表(user)和列族(info,data)
















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值