HDFS数据转移至HBase
将HDFS文件系统中的数据转移到HBase表中,已知HDFS系统的根目录有一个存储学生信息的文件student.txt,文件中共有三列,分别代表学号,姓名和年龄。该文件的内容如下:
004 WangQiang 28
005 ZhaoLong 36
006 LINing 27
现在需要使用MapReduce读取student.txt文件中的数据,将学号作为rowKey添加到HBase中的“student_new”表,
引入的jar表与HBase MapReduce数据转移(一)节中的相同
(1)创建ReadHDFSStudentMapper.java类主要用于读取HDFS文件中的数据,然后将读取到的数据进行分割并存储到HBase的put对象中,完整代码如下:
package org.data.bigdata.hbase.hdfs.hbase.mapreduce; 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; import java.io.IOException; /** * 读取HDFS中的文件student.txt的数据 */ public class ReadHDFSStudentMapper extends Mapper<LongWritable,Text,ImmutableBytesWritable,Put> { /** * 接收hdfs中的数据,参数key为一行数据的下标位置,value为一行数据 * @param key * @param value * @param context * @throws IOException * @throws InterruptedException */ @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {// 该方法读取文件时,一行一行顺序读取解析 // 将读取的一行数据转为字符串 String lineValue = value.toString(); // 将一行数据根据'\t' 分割成String 数组 String[] values = lineValue.split("\t"); // 取出每一个值 String rowKey = values[0]; // 学号 String name = values[1];// 姓名 String age = values[2]; // 年龄 // 将rowkey转为ImmutableBytesWritable类型,便于Reduce阶段接收 ImmutableBytesWritable rowKeyWritable = new ImmutableBytesWritable(Bytes.toBytes(rowKey)); // 创建一整行数据,用于存储一整行数据 Put put = new Put(Bytes.toBytes(rowKey)); // 向Put中对象添加数据,参数分别为:列族,列,值 put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes(name)); put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes(age)); // 写数据到reduce阶段,键为HBase表的rowkey(学号),值为Put对象 context.write(rowKeyWritable,put); } }
(2)新建WriteHBaseStudentReducer.java类主要用于接收Map阶段读取的数据,并将数据写入到HBase中,完整代码如下:
package org.data.bigdata.hbase.hdfs.hbase.mapreduce; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.mapreduce.TableReducer; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; /** * 将接收到的数据写入到HBase表中 */ public class WriteHBaseStudentReducer extends TableReducer<ImmutableBytesWritable,Put,NullWritable> { /** * 接收Map()方法的输出,参数key和values的类型需与map()方法的输出一致 * @param key * @param values * @param context * @throws IOException * @throws InterruptedException */ @Override protected void reduce(ImmutableBytesWritable key, Iterable<Put> values, Context context) throws IOException, InterruptedException { for(Put put : values){ //将数据写入HBase表中,输出的key可以为空,因为行键在put对象中已经包含 context.write(NullWritable.get(),put); } } }
(3)新建HDFS2HBaseMRRunner.java类用于构建与执行MapReduce任务
package org.data.bigdata.hbase.hdfs.hbase.mapreduce; 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.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.Job; import java.io.IOException; /** * 改类用于MapReduce任务的构建与执行 */ public class HDFS2HBaseMRRunner { /** * main方法,任务执行的入口 * @param args */ public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { // 创建Configuration配置类 Configuration configuration = HBaseConfiguration.create(); // 创建Job任务,指定任务名称 Job job= Job.getInstance(configuration,"hbase_mr_job2"); // 设置任务运行主类 job.setJarByClass(HDFS2HBaseMRRunner.class); // 设置文件输入路径,centoshadoop1为Hadoop集群NameNode节点的主机名 Path inputPath = new Path("hdfs://centoshadoop1:8020/student.txt"); // 根据自己的路径调整 FileInputFormat.addInputPath(job,inputPath); // 设置Mapper类 job.setMapperClass(ReadHDFSStudentMapper.class); // Mapper输出的key的类型 job.setMapOutputKeyClass(ImmutableBytesWritable.class); // Mapper输出来的value的类型 job.setMapOutputValueClass(Put.class); // 初始化Reducer任务 TableMapReduceUtil.initTableReducerJob("student_new", // 数据目的地表名 WriteHBaseStudentReducer.class,job); // 指定Reduce类与任务job // 设置Reduce数量,最少1个 job.setNumReduceTasks(1); // 执行任务 boolean isSuccess = job.waitForCompletion(true); if(!isSuccess){ throw new IOException("任务运行错误!!"); } System.exit(isSuccess? 0 : 1); } }
(4)运行MapReduce任务
将该maven打包: 列如打包为:hbase_hdfs_mr.jar,执行如下命令运行
java -jar hbase_hdfs_mr.jar org.data.bigdata.hbase.hdfs.hbase.mapreduce.HDFS2HBaseMRRunner
任务运行结束后,进入hbase shell中输入
scan 'student_new' 查看导入的数据