HBase 用MapReduce導入MySQL中的數據到HBase

用MapReduce導入MySQL中的數據到HBase

將MySQL表的數據先導入到HDFS文件中(比如TSV格式),編寫MapReduce將文本文件數據轉換爲HFile文件,加載到HBase表中。

  • 第一步、用Sqoop在Hive中創建表
/export/servers/sqoop/bin/sqoop create-hive-table \
--connect jdbc:mysql://bd001:3306/tags_dat2 \
--table tbl_logs \
--username root \
--password 123456 \
--hive-table tags_dat2.tbl_logs \
--fields-terminated-by '\t' \
--lines-terminated-by '\n'
  • 第二步、sqoop導入MySQL表數據到Hive表
/export/servers/sqoop/bin/sqoop import \
--connect jdbc:mysql://bd001:3306/tags_dat2 \
--username root \
--password 123456 \
--table tbl_logs \
--direct \
--hive-overwrite \
--delete-target-dir \
--fields-terminated-by '\t' \
--lines-terminated-by '\n' \
--hive-table tags_dat2.tbl_logs \
--hive-import \
--num-mappers 20

第三步、編寫MapReduce導入數據至HBase表

  • 1,創建HBase 表,設置預分區
create 'tbl_logs', 'detail', SPLITS => ['49394']
  • 2,工具類Constants,定義常量值
package com.czxy.demo08;

import org.apache.hadoop.hbase.util.Bytes;

import java.util.ArrayList;
import java.util.List;

/**
 * 定義常量
 */
interface Constants {
	// hive表數據目錄
	String INPUT_PATH = "hdfs://bd001:8020/user/hive/warehouse/tags_dat2.db/tbl_logs";
	// 生成的hfile目錄
	String HFILE_PATH = "hdfs://bd001:8020/datas/output_hfile/tbl_logs";
	// 表名
	String TABLE_NAME = "tbl_logs";
	// 列簇名稱
	byte[] COLUMN_FAMILY = Bytes.toBytes("detail");

	// 表字段
	List<byte[]> list = new ArrayList<byte[]>() {
		private static final long serialVersionUID = -6125158551837044300L;

		{ //
			add(Bytes.toBytes("id"));
			add(Bytes.toBytes("log_id"));
			add(Bytes.toBytes("remote_ip"));
			add(Bytes.toBytes("site_global_ticket"));
			add(Bytes.toBytes("site_global_session"));
			add(Bytes.toBytes("global_user_id"));
			add(Bytes.toBytes("cookie_text"));
			add(Bytes.toBytes("user_agent"));
			add(Bytes.toBytes("ref_url"));
			add(Bytes.toBytes("loc_url"));
			add(Bytes.toBytes("log_time"));
		} //
	};

}
  • 3,MapReduce程序(本地運行)

​ 使用Java語言,編寫MapReduce程序,讀取Hive表中數據文件,使用HFileOutputFormat2輸出格式,保存數據至HFile文件,再加載到HBase表中。

package com.czxy.demo08;

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.*;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2;
import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.io.IOException;

/**
 * 將Hive表數據轉換爲HFile文件並移動HFile到HBase
 */
public class LoadLogsToHBaseMapReduce
		extends Configured implements Tool {

	// 連接HBase Connection對象
	private static Connection connection = null ;

	/**
	 * 定義Mapper類,讀取CSV格式數據,轉換爲Put對象,存儲HBase表
	 */
	static class LoadLogsToHBase extends Mapper<LongWritable, Text, ImmutableBytesWritable, Put> {

		@Override
		protected void map(LongWritable key, Text value, Context context)
				throws IOException, InterruptedException {
			// 按照分隔符分割數據,分隔符爲 逗號
			String[] split = value.toString().split("\\t");
			if (split.length == Constants.list.size()) {
				// 構建Put對象,將每行數據轉換爲Put
				Put put = new Put(Bytes.toBytes(split[0]));
				for (int i = 1; i < Constants.list.size(); i++) {
					put.addColumn(//
							Constants.COLUMN_FAMILY, //
							Constants.list.get(i), //
							Bytes.toBytes(split[i]) //
					);
				}
				// 將數據輸出
				context.write(new ImmutableBytesWritable(put.getRow()), put);
			}
		}

	}

	@Override
	public int run(String[] args) throws Exception {
		// a. 獲取配置信息對象
		Configuration configuration = super.getConf() ;

		// b. 構建Job對象Job
		Job job = Job.getInstance(configuration);
		job.setJobName(this.getClass().getSimpleName());
		job.setJarByClass(LoadLogsToHBaseMapReduce.class);

		// c. 設置Job
		FileInputFormat.addInputPath(job, new Path(Constants.INPUT_PATH));
		job.setMapperClass(LoadLogsToHBase.class);
		// TODO: 設置輸出格式爲HFileOutputFormat2
		job.setMapOutputKeyClass(ImmutableBytesWritable.class);
		job.setMapOutputValueClass(Put.class);
		job.setOutputFormatClass(HFileOutputFormat2.class);

		// TODO: 判斷輸出目錄是否存在,如果存在就刪除
		FileSystem hdfs = FileSystem.get(configuration) ;
		Path outputPath = new Path(Constants.HFILE_PATH) ;
		if(hdfs.exists(outputPath)){
			hdfs.delete(outputPath, true) ;
		}
		// d. 設置輸出路徑
		FileOutputFormat.setOutputPath(job, outputPath);

		// TODO:獲取HBase Table,對HFileOutputFormat2進行設置
		Table table = connection.getTable(TableName.valueOf(Constants.TABLE_NAME));
		HFileOutputFormat2.configureIncrementalLoad( //
				job, //
				table, //
				connection.getRegionLocator(TableName.valueOf(Constants.TABLE_NAME)) //
		);

		// 提交運行Job,返回是否執行成功
		boolean isSuccess = job.waitForCompletion(true);
		return isSuccess ? 0 : 1;
	}


	public static void main(String[] args) throws Exception {
		// 獲取Configuration對象,讀取配置信息
		Configuration configuration = HBaseConfiguration.create();
		// 獲取HBase 連接Connection對象
		connection = ConnectionFactory.createConnection(configuration);
		
		// 運行MapReduce將數據文件轉換爲HFile文件
		int status = ToolRunner.run(configuration, new LoadLogsToHBaseMapReduce(), args);
		System.out.println("HFile文件生成完畢!~~~");

		// TODO:運行成功時,加載HFile文件數據到HBase表中
		if (0 == status) {
			// 獲取HBase Table句柄
			Admin admin = connection.getAdmin();
			Table table = connection.getTable(TableName.valueOf(Constants.TABLE_NAME));
			// 加載數據到表中
			LoadIncrementalHFiles load = new LoadIncrementalHFiles(configuration);
			load.doBulkLoad(
					new Path(Constants.HFILE_PATH), //
					admin, //
					table, //
					connection.getRegionLocator(TableName.valueOf(Constants.TABLE_NAME)) //
			);
			System.out.println("HFile文件移動完畢!~~~");
		}
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章