HBASE总结

HBASE基本知识点

  1. HBASE是一个分布式的,列式数据库
  2. HBASE中的行由行键和一个或多个列组成,行键类似于关系型数据库的主键索引,按照字母顺序排序
  3. HBASE中列族由一个或多个列组成,可以理解为将列进行分组,列族一般不超过3个
  4. HBASE中单元格,类似于关系型数据库中某个字段的值,是通过行键,列族,列三者来定位,单元格包含数据和时间戳,数据类型为字节数据byte[]类型,时间戳代表版本
  5. 可将HBASE理解为一个类似于键值对的数据库,通过行键,列族,列,时间戳可以定位到具体的单元格,时间戳可省略,因为默认取最新的数据

HBASE集群架构

HBASE架构采用主从方式,类似于HDFS的namenode和datanode,HBASE集群由HMaster节点、HRegionServer节点、ZooKeeper集群组成,所有节点通过zookeeper协调,HMaster通过ZooKeeper获取HRegionServer的状态并进行管理,底层通过HRegionServer将数据存储在HDFS中

HBASE SHELL基本命令

操作命令注意
建表create ‘t1’,‘f1’建表时需同时指定表名t1和列族名称f1
添加数据put ‘t1’,‘row1’,‘f1:name’,‘zhangsan’表 t1,行键 row1,列族及列 f1:name,值 zhangsan
全表扫描scan ‘t1’表名 t1
查询某一行get ‘t1’,‘row1’表名 t1,行键 row1
修改表中数据put ‘t1’,‘row1’,‘f1:name’,lisi’表名 t1,行键 row1,列族及列 f1:name,值 lisi
删除特定单元格delete ‘t1’,‘row1’,‘f1:name’表名 t1,行键 row1,列族及列 f1:name
删除一整行deleteall ‘t1’,‘row2’表名 t1,行键 row2
禁用表disable ‘t1’
删除整张表drop ‘t1’若要完全删除一张表,需先执行disable,再执行drop
列出所有表list
查询表中行数count ‘t1’
判断表是否存在exists ‘t1’

HBASE JAVA API操作

创建表
package walker_0325;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;

public class HbaseCreateTable {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		//创建hbase配置对象
		Configuration conf = HBaseConfiguration.create();
		
		//指定zookeeper集群地址
		conf.set("hbase.zookeeper.quorum", "192.168.220.129:2181,192.168.220.130:2181,192.168.220.131:2181");
		
		//创建连接对象connection
		Connection conn = ConnectionFactory.createConnection(conf);
		
		//得到数据库管理员对象
		Admin admin = conn.getAdmin();
		
		//创建表描述,并指定表名
		TableName tableName = TableName.valueOf("t2");
		HTableDescriptor desc = new HTableDescriptor(tableName);
		
		//创建列族描述
		HColumnDescriptor family = new HColumnDescriptor("f2");
		
		//指定列族
		desc.addFamily(family);
		
		//创建表
		admin.createTable(desc);
		System.out.println("create table success");
		
	}

}

建表整体上可认为分两步进行,即 配环境连库,管理员建表
配环境连库:

  1. 操作HBASE,需配置HBASE环境,HBaseConfiguration.create();
  2. HBASE通过zookeeper实现节点间协调, conf.set(“hbase.zookeeper.quorum”,“集群…”);
  3. 连接数据库,ConnectionFactory.createConnection(conf);

管理员建表:

  1. 获取管理员用户,conn.getAdmin();
  2. 设置表名及表描述,new HTableDescriptor(TableName.valueOf(“t2”));
  3. 列族描述,new HColumnDescriptor(“f2”);
  4. 表与列族关联,desc.addFamily(family);
  5. 管理员建表,admin.createTable(desc);
添加数据
package walker_0325;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

/**
 * @author Administrator
 * @date 2020年3月25日 上午10:53:59
 * 向hbase表中添加数据
 */
public class HBasePutData {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		//创建HBASE配置对象
		Configuration conf = HBaseConfiguration.create();
		
		//指定zookeeper集群地址
		conf.set("hbase.zookeeper.quorum", "192.168.220.129:2181,192.168.220.130:2181,192.168.220.131:2181");
		
		//创建数据库连接对象connection
		Connection conn = ConnectionFactory.createConnection(conf);
		
		//Table负责与记录相关的操作,如增删改查等
		TableName tableName = TableName.valueOf("t2");
		Table table = conn.getTable(tableName);
		
		//设置rowkey
		Put put = new Put(Bytes.toBytes("row1"));
		
		//添加列数据,指定列族,列名,列值
		put.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("name"), Bytes.toBytes("xiaoming"));
		put.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("age"), Bytes.toBytes("20"));
		put.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("address"), Bytes.toBytes("beijing"));
		
		
		//设置rowkey
		Put put2 = new Put(Bytes.toBytes("row2"));
		
		//添加列数据,指定列族,列名,列值
		put2.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("name"), Bytes.toBytes("xiaoming2"));
		put2.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("age"), Bytes.toBytes("22"));
		put2.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("address"), Bytes.toBytes("beijing2"));		

		
		//设置rowkey
		Put put3 = new Put(Bytes.toBytes("row3"));
		
		//添加列数据,指定列族,列名,列值
		put3.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("age"), Bytes.toBytes("25"));
		put3.addColumn(Bytes.toBytes("f2"), Bytes.toBytes("address"), Bytes.toBytes("beijing3"));		
		
		
		//执行添加数据
		table.put(put);
		table.put(put2);
		table.put(put3);
		
		//释放资源
		table.close();
		
		System.out.println("put data success");
	}
}

整体上也可认为分两步进行,即配环境连库,put对象装数
配环境连库:与建表一致,HBASE配置,zookeeper配置,连库
put对象装数:

  1. 先得知道往哪个表里装,conn.getTable(TableName.valueOf(“t2”));
  2. 指定rowkey,建立put对象,Put put = new Put(Bytes.toBytes(“row1”));
  3. 指定列族,列名,值,添加数据,put.addColumn(Bytes.toBytes(“f2”), Bytes.toBytes(“name”), Bytes.toBytes(“xiaoming”));
查询数据
package walker_0325;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Table;

/**
 * @author Administrator
 * @date 2020年3月25日 上午11:13:04
 * 查询表t2行键为row1的一行数据
 */
public class HBaseGetData {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		//创建hbase配置对象
		Configuration conf = HBaseConfiguration.create();
		
		//指定zookeeper集群地址
		conf.set("hbase.zookeeper.quorum", "192.168.220.129:2181,192.168.220.130:2181,192.168.220.131:2181");
		
		//获得数据库连接
		Connection conn = ConnectionFactory.createConnection(conf);
		
		//获得Table对象,指定查询表名,Table负责与记录相关的操作,如增删改查等
		Table table = conn.getTable(TableName.valueOf("t2"));
		
		//创建Get对象,根据rowkey查询,rowkey=row1
		Get get = new Get("row1".getBytes());
		
		//查询数据,取得结果集
		Result r = table.get(get);
		
		//循环输出每个单元格的值
		for (Cell cell : r.rawCells()) {
			//取得当前单元格所属列族名称
			String family = new String(CellUtil.cloneFamily(cell));
			//取得当前单元格所属列名称
			String qualifier = new String(CellUtil.cloneQualifier(cell));
			//取得当前单元格的列值
			String value = new String(CellUtil.cloneValue(cell));
			//输出结果
			System.out.println("列族"+family+"; 列名"+qualifier+"; 值"+value);
			
		}
	}

}

整体上分三步,配环境连库,get对象取一行,foreach取值
配环境连库,与前两个一致
get对象取一行

  1. 拿表名,conn.getTable(TableName.valueOf(“t2”));
  2. 指定rowkey,new Get(“row1”.getBytes());
  3. 取出数据集,table.get(get);

foreach取值
循环取到每个单元格的值

删除数据
package walker_0325;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

/**
 * @author Administrator
 * @date 2020年3月25日 上午11:30:27
 * 删除表t2中行键为row1的一整条数据
 */
public class HBaseDeleteData {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		//创建hbase配置对象
		Configuration conf = HBaseConfiguration.create();
		
		//设置集群zookeeper
		conf.set("hbase.zookeeper.quorum", "192.168.220.129:2181,192.168.220.130:2181,192.168.220.131:2181");
		
		//创建connection对象
		Connection conn = ConnectionFactory.createConnection(conf);
		
		Table table = conn.getTable(TableName.valueOf("t2"));
		
		//创建删除对象delete,根据rowkey删除一整条 "row1".getBytes()
		Delete delete = new Delete(Bytes.toBytes("row1"));
		table.delete(delete);
		
		//释放资源
		table.close();
		System.out.println("删除完成");
		
	}

}

整体分两步,配环境连库,delete对象删数
配环境连库与之前一致
delete对象删数

  1. 拿表名,conn.getTable(TableName.valueOf(“t2”));
  2. 指定删除rowkey,new Delete(Bytes.toBytes(“row1”));
  3. 删除,table.delete(delete);

HBASE过滤器

package walker_0325;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.FamilyFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.QualifierFilter;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.filter.ValueFilter;
import org.apache.hadoop.hbase.util.Bytes;

/**
 * @author Administrator
 * @date 2020年3月25日 下午3:54:35
 * 使用HDFS过滤器查询
 */
public class HBaseUseFilter {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		
		//HBase环境配置对象
		Configuration conf = HBaseConfiguration.create();
		
		//设置zookeeper集群信息
		conf.set("hbase.zookeeper.quorum", "192.168.220.129:2181,192.168.220.130:2181,192.168.220.131:2181");
		
		//创建connection对象建立连接
		Connection conn = ConnectionFactory.createConnection(conf);
		
		//获取表
		Table table = conn.getTable(TableName.valueOf("t2"));
		
		
		/**
		 * 1.行键过滤器
		 */
		System.out.println("行键过滤器");
		//创建Scan对象
		Scan scan = new Scan();
		//创建一个过滤器,筛选行键等于row1的数据
		RowFilter filter = new RowFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("row2")));
		//设置过滤器
		scan.setFilter(filter);
		//查询数据,返回结果数据集
		ResultScanner rs = table.getScanner(scan);
		for (Result res : rs) {
			System.out.println(res);
		}
		
		/**
		 * 2.列族过滤器
		 */
		System.out.println("列族过滤器");
		Scan scan2 = new Scan();
		//创建一个过滤器,筛选列族为f1的所有数据
		FamilyFilter filter2 = new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("f2")));
		scan2.setFilter(filter2);
		ResultScanner rs2 = table.getScanner(scan2);
		for (Result result2 : rs2) {
			System.out.println(result2);
		}
		
		
		/**
		 * 3.列过滤器
		 */
		System.out.println("列过滤器");
		Scan scan3 = new Scan();
		QualifierFilter filter3 = new QualifierFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("address")));
		scan3.setFilter(filter3);
		ResultScanner rs3 = table.getScanner(scan3);
		for (Result result3 : rs3) {
			System.out.println(result3);
		}

		
		/**
		 * 4.值过滤器
		 */
		System.out.println("值过滤器");
		Scan scan4 = new Scan();
		ValueFilter filter4 = new ValueFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("xiaoming2")));
		scan4.setFilter(filter4);
		ResultScanner rs4 = table.getScanner(scan4);
		for (Result result4 : rs4) {
			System.out.println(result4);
		}
		
		/**
		 * 5.单列值过滤器
		 */
		//筛选出age列不为22的所有数据
		System.out.println("单列值过滤器");
		Scan scan5 = new Scan();
		Filter filter5 = new SingleColumnValueExcludeFilter(Bytes.toBytes("f2"),
				Bytes.toBytes("age"), 
				CompareOp.NOT_EQUAL, 
				new SubstringComparator("22"));
		//如果某行name列不存在,哪个该行将被过滤掉,false则不进行过滤,默认为false
		((SingleColumnValueFilter)filter5).setFilterIfMissing(true);
		scan5.setFilter(filter5);
		ResultScanner rs5 = table.getScanner(scan5);
		for (Result result5 : rs5) {
			System.out.println(result5);
		}
		
		
		/**
		 * 6.多条件过滤
		 */
		System.out.println("多条件过滤");
		Scan scan6 = new Scan();
		
		//创建过滤器,查询年龄<=30的所有数据
		Filter filter6 = new SingleColumnValueExcludeFilter(Bytes.toBytes("f2"), 
				Bytes.toBytes("age"), 
				CompareOp.LESS_OR_EQUAL, 
				Bytes.toBytes("30"));
		//创建过滤器,查询年龄>=16的所有数据
		Filter filter7 = new SingleColumnValueExcludeFilter(Bytes.toBytes("f2"), 
				Bytes.toBytes("age"), 
				CompareOp.GREATER_OR_EQUAL, 
				Bytes.toBytes("16"));
		
		//创建过滤器集合对象
		FilterList filterList = new FilterList();
		//添加过滤器
		filterList.addFilter(filter6);
		filterList.addFilter(filter7);
		
		scan6.setFilter(filterList);
		ResultScanner rs6 = table.getScanner(scan6);
		for (Result result6 : rs6) {
			System.out.println(result6);
		}
		
	}

}

过滤器可以理解为sql中的where条件
使用过滤器整体上四步走

  1. 创建scan对象
  2. 针对不同过滤创建过滤器
  3. scan设置过滤器
  4. 获取扫描结果
  5. foreach循环返回结果

HBASE MapReduce数据转移

不同表间数据转移
package walker_03252;

import java.io.IOException;

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;




/** map类
 * @author Administrator
 * @date 2020年3月25日 下午6:09:16
 * 从hbase中读取表student的指定列数据
 */
public class ReadStudentMapper extends TableMapper<ImmutableBytesWritable, Put>{

	/**
	 * 参数key为表中的行键,value为表中的一行数据
	 */
	@Override
	protected void map(ImmutableBytesWritable key, Result value,Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		//新建put对象,传入行键
		Put put = new Put(key.get());
		//遍历一行数据的每一个单元格
		for (Cell cell: value.rawCells()) {
			//如果当前单元格所属列族为info
			if ("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))) {
				//如果当前单元格的列限定符为name
				if ("name".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
					//将该单元格加入到put对象中
					put.add(cell);
					//如果当前单元格的列限定符为age
				}else if ("age".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
					//将该单元格加入到put对象中
					put.add(cell);
				}
			}
		}
		
		//将put对象写入到context中作为map的输出
		context.write(key, put);
		
	}
}

TableMapper是Mapper类的简化版本,只有两个参数,输出key和输出value,因为输入key和输入value值是固定的,输入key为ImmutableBytesWritable,为hbase中的行键,输入value为Result,为hbase中的一行数据。


package walker_03252;

import java.io.IOException;

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;

/** reduce类
 * @author Administrator
 * @date 2020年3月25日 下午6:20:39
 * 将数据写入到hbase另一张表student_new中
 */
public class WriteStudentReducer extends TableReducer<ImmutableBytesWritable, Put, NullWritable>{

	/**
	 * 接收map方法的输出,参数key和value的类型需与map方法的输出一致
	 */
	
	@Override
	protected void reduce(ImmutableBytesWritable key, Iterable<Put> values,Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		for (Put put : values) {
			//将数据写入hbase表中,输出的key可以为空,因为行键在put对象中已经包含
			context.write(NullWritable.get(), put);
		}
	}
	
}

TableReducer是Reducer类的简化版本,泛型参数仅有输入key,输入value,输出key三个,输出value的类型是固定的,为HBASE抽象Mutation类型,Mutation有4个子类,分别为Append,Delete,Increment,Put,输出value只能是这四个中一个,


package walker_03252;

import java.io.IOException;

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.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.mapreduce.Job;

/** 主类
 * @author Administrator
 * @date 2020年3月25日 下午7:13:00
 * mapreduce任务构建与执行类
 */
public class StudentMRRunner {

	public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
		// TODO Auto-generated method stub

		//创建configuration实例
		Configuration conf = HBaseConfiguration.create();
		
		//创建job任务,指定任务名称
		Job job = Job.getInstance(conf,"hbase_mr_job");
		//设置任务运行主类
		job.setJarByClass(StudentMRRunner.class);
		//创建Scan数据扫描对象
		Scan scan = new Scan();
		//是否缓存数据块,默认true,设置为false节省了交换缓存的操作消耗,可以提升MR任务的有效率
		scan.setCacheBlocks(false);
		//每次RPC请求从HBase表中取得的数据行数
		scan.setCaching(500);
		//初始化Mapper任务
		TableMapReduceUtil.initTableMapperJob("student", //数据源表名
				scan, //scan扫描控制器
				ReadStudentMapper.class, //指定mapper类
				ImmutableBytesWritable.class, //mapper的输出key类型
				Put.class, //mapper输出的value类型
				job //指定任务Job
				);
		//初始化reducer任务
		TableMapReduceUtil.initTableReducerJob("student_new", //数据目的地表名
				WriteStudentReducer.class, //指定reudcer类 
				job //指定任务Job
				);
		
		//设置reduce数量,最少1个
		job.setNumReduceTasks(1);
		//执行任务
		boolean isSuccess = job.waitForCompletion(true);
		
		if (!isSuccess) {
			throw new IOException("任务运行错误");
		}
		
		System.exit(isSuccess ? 0 : 1);
		
	}

}

与mapreduce不同的是,使用TableMapReduceUtil来进行初始化map和reduce任务。

HDFS数据转移至HBASE
//hdfs中数据
004	WangQiang	28
005	ZhaoLong	36
006	LiNing	27
package walker_03253;

import java.io.IOException;

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;



/**
 * @author Administrator
 * @date 2020年3月25日 下午7:52:03
 * 读取HDFS中的文件student.txt的数据
 */
public class ReadHDFSStudentMapper extends Mapper<LongWritable, Text, ImmutableBytesWritable, Put> {

	/**
	 * 接收HDFS中的数据
	 * 参数key为一行数据的下标位置,value为一行数据
	 */
	
	@Override
	protected void map(LongWritable key, Text value,Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		
		//将读取的一行数据转换为字符串
		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 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);

	}
	
	
}

将数据存到string数组,再把行键转为对应类型,将行键和数据添加到put对象。


package walker_03253;

import java.io.IOException;

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;



/**
 * @author Administrator
 * @date 2020年3月25日 下午8:07:40
 * 将接收到的数据写入到HBASE表中
 */
public class WriteHBaseStudentReducer extends TableReducer<ImmutableBytesWritable, Put, NullWritable> {

	/**
	 * 接收map方法的输出,参数key和value的类型需与map方法的输出一致
	 */
	@Override
	protected void reduce(ImmutableBytesWritable key, Iterable<Put> values,Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		
		for (Put put : values) {
			//将数据写入hbase表,输出的key可以为空,因为行键在put对象中已经包含
			context.write(NullWritable.get(), put);
		}
	}
	
}


package walker_03253;

import java.io.IOException;

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.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

/**
 * @author Administrator
 * @date 2020年3月25日 下午8:19:11
 * mapreduce任务构建与执行类
 */
public class HDFS2HBaseMRRunner {

	public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
		// TODO Auto-generated method stub

		//创建hbase配置对象
		Configuration conf = HBaseConfiguration.create();
		//创建job并指定任务名称
		Job job = Job.getInstance(conf,"hbase_mr_job2");
		//设置任务运行主类
		job.setJarByClass(HDFS2HBaseMRRunner.class);
		
		//设置文件输入路径
		Path inputPath = new Path("hdfs://walker001:9000/test/0325/student.txt");
		//job与文件路径关联
		FileInputFormat.addInputPath(job, inputPath);
		
		//设置mapper类
		job.setMapperClass(ReadHDFSStudentMapper.class);
		//mapper类的输出key类型
		job.setMapOutputKeyClass(ImmutableBytesWritable.class);
		//mapper类的输出value类型
		job.setMapOutputValueClass(Put.class);
		
		//初始化reduce任务
		TableMapReduceUtil.initTableReducerJob("student_new",//目标表
				WriteHBaseStudentReducer.class,//reducer类 
				job //任务job
				);
		
		//设置reduce任务数量
		job.setNumReduceTasks(1);
		
		//执行任务
		
		boolean isSuccess = job.waitForCompletion(true);
		
		if (!isSuccess) {
			throw new IOException("任务运行异常");
		}
		
		System.exit(isSuccess ? 0 : 1);
		

	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值