HBase和MapReduce结合

一、准备

  • 让Hadoop加载HBase的jar包
    • 法一:将HBase中的所有的jar包都导入到Hadoop的lib目录下
    • 法二:将HBase的包地址写到Hadoop的hadoop-env.sh文件中
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:HBase的目录/lib/*

二、运行官方MapReduce任务

  • 案例一:统计t1表的Cell的数量
hadoop jar hbase-server-1.3.1.jar CellCounter t1 /hbasemr/cellcount
  • 案例二:统计t1表的行数
hadoop jar hbase-server-1.3.1.jar rowcounter t1
  • 案例三:向HBase导入数据
    • 向hbase中导入数据,需要手动建表,需要把数据上传到HDFS,注意数据中字段的顺序要和-Dimporttsv.columns的顺序一致
    • HBASE_ROW_KEY:代表rowkey列
hadoop jar hbase-server-1.3.1.jar importtsv -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:age,info:gender t2 /hbaseimport

三、自定义MapReduce任务

3.1 案例一

  • 需求:MR读取hbase中t2表的部分数据,写入到t4表中
  • Mapper
package hbase.mr.tiger;


/*
* 1、MR读取hbase中t2表的部分数据,写入到t4表中
*   读入输入目录中的数据(t2) --- Map --- Reduce --- 写出到指定的目录(t4)
*
* 2、目前读取的是HBase中的数据,而不是文本文件,所以不能使用默认的TextInputFormat,自然RecordReader泛型无法确定
*   需要先确定什么样的输入格式可以读取HBase中的表
*   在HBase中默认使用TableInputFormat输入格式,
*       切片,一个region切一片
*       RecordReader:RecordReader<ImmutableBytesWritable, Result>
*            ImmutableBytesWritable:rowkey
*            Result:一行的数据
*
* 3、输出的数据应该是一个put对象
*   在Maper中,数据如果需要排序,必须作为key,如果不需要排序可以作为value
*
* 4、如果Mapper输出的value是put类型,会自动设置Combiner
*   无法避免设置设置Combiner时,可以让Combiner的逻辑无法执行
*   保证输出的key不能相等,
*
* 5、Hadoop MR处理的数据都必须是key-value
*       在Hadoop中,只要有Reducer,那么此时key-value必须实现序列化
*       Wriable,key实现WritableComarable
*           value实现Writable
*
* 为什么Put没有实现Wriable,程序依然没有报错
*   HBase自己提供了序列化器
*
* */

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.Text;

import java.io.IOException;

public class Example1Mapper extends TableMapper<Text , Put> {
    private Text out_key = new Text();

    @Override
    protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException {
        out_key.set(Bytes.toString(key.copyBytes()));
        // 构建put对象,并且封装了rowkey
        Put put = new Put(key.copyBytes());

        Cell[] rawCells = value.rawCells();
        for (Cell rawCell : rawCells) {
            if (Bytes.toString(CellUtil.cloneFamily(rawCell)).equals("info")
                    && Bytes.toString(CellUtil.cloneQualifier(rawCell)).equals("age")
                    && Bytes.toString(CellUtil.cloneValue(rawCell)).equals("20")) {

                //

                // 把符合要求的一行所有的单元格放入到put对象中
                for (Cell cell : rawCells) {
                    put.add(cell);
                }
                // 把整个put写出
                context.write(out_key, put);

            }
        }
    }
}
  • Reducer
package hbase.mr.tiger;

/*
* 1、Reducer输出的类型必须是Mutation,是固定的
*   Mutation是所有写数据类型的父类
*
*
* Reducer的任务就是将Mapper输出所的所有记录写出
* */

import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.io.Text;

public class Example1Reducer extends TableReducer<Text, Put, Text> {

}
  • Driver
package hbase.mr.tiger;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;

import java.io.IOException;

public class Example1Driver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        // 创建一个job的Configuration
        Configuration conf = HBaseConfiguration.create();

        // 创建一个job
        Job job = Job.getInstance(conf);

        job.setJobName("example1");

        job.setJarByClass(Example1Driver.class);

        Scan scan = new Scan();
        // 配置job Mapper配置
        TableMapReduceUtil.initTableMapperJob("t2", scan, Example1Mapper.class, Text.class, Put.class, job);

        // 配置job Reducer配置
        TableMapReduceUtil.initTableReducerJob("t4", Example1Reducer.class, job);

        // 运行
        job.waitForCompletion(true);
    }

}

3.2 案例二

  • 需求:MR读取HDFS中的数据,写入到hbase中
  • Mapper
package hbase.mr.hdfstohbase;

/*
* 1、MR读取HDFS中的数据,写入到hbase中
*   InputFormat无需使用TableInputFormat
*
* */


import org.apache.hadoop.hbase.client.Put;
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;

import java.io.IOException;

public class Example2Mapper extends Mapper<LongWritable, Text, Text, Put> {
    private Text out_key = new Text();

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] words = value.toString().split("\t");

        // 封装rowkey列
        out_key.set(words[0]);

        Put put = new Put(Bytes.toBytes(words[0]));

        put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("category"), Bytes.toBytes(words[1]));

        context.write(out_key, put);


    }
}
  • Reducer
package hbase.mr.hdfstohbase;

import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.io.Text;

public class Example2Reducer extends TableReducer<Text, Put, Text> {
}
  • Driver
package hbase.mr.hdfstohbase;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

import java.io.IOException;

public class Example2Driver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        // 创建一个job的Configuration
        Configuration conf = HBaseConfiguration.create();

        // 创建一个job
        Job job = Job.getInstance(conf);

        job.setJobName("example2");

        job.setJarByClass(Example2Driver.class);


        // 设置job使用的Mapper的类型
        job.setMapperClass(Example2Mapper.class);

        // 设置job使用的Mapper的输出的类型
        job.setMapOutputKeyClass(Text.class);
        job.setOutputValueClass(Put.class);

        // 设置输入目录
        FileInputFormat.setInputPaths(job, new Path("hdfs://master:9000/hive/warehouse/movie_info/data2"));


        // 配置job Reducer配置
        TableMapReduceUtil.initTableReducerJob("t5", Example2Reducer.class, job);

        // 运行
        job.waitForCompletion(true);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_38689352/article/details/113753181