计算HBase指定表中所有用户的平均年龄写入到HDFS中

HBase表中的数据是通过上一篇博客导入的:从HDFS读取文件中的数据写入到HBase的表中


import java.io.IOException;
import java.util.List;

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.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Result;
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.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class HBASE2HDFS extends Configured implements Tool{
	private static final String ZK_CONNECT_KEY = "hbase.zookeeper.quorum";
	private static final String ZK_CONNECT_VALUE = "hadoop2:2181,hadoop3:2181,hadoop4:2181";

	@Override
	public int run(String[] arg0) throws Exception {
		Configuration conf = new Configuration();
		conf.set("fs.defaultFS", "hdfs://myha1");
		conf.addResource("config/core-site.xml");
		conf.addResource("config/hdfs-site.xml");
		System.setProperty("HADOOP_USER_NAME", "hadoop");
		
		FileSystem fs = FileSystem.get(conf);
		
		Configuration config = HBaseConfiguration.create(conf);
		config.set(ZK_CONNECT_KEY, ZK_CONNECT_VALUE);
		
		
		Job job = Job.getInstance(config);
		job.setJarByClass(HBASE2HDFS.class);
		
		Scan scan = new Scan();
		scan.addColumn("info".getBytes(), "age".getBytes());
		TableMapReduceUtil.initTableMapperJob("users".getBytes(), scan, H2H_Mapper.class, Text.class, IntWritable.class, job, false);
		
		job.setReducerClass(H2H_Reducer.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(DoubleWritable.class);
		
		if(fs.exists(new Path("/student/output"))){
			fs.delete(new Path("/student/output"),true);
		}
		
		FileOutputFormat.setOutputPath(job, new Path("/student/output"));
		
		boolean isDone = job.waitForCompletion(true);
		
		return isDone ? 0:1;
	}
	
	
	public static void main(String[] args) throws Exception {
		int isDone = ToolRunner.run(new HBASE2HDFS(), args);
		System.exit(isDone);
	}
	
	
	
	/**
	 * 	get 'stduent','rk01'   ====  Result
	 * 
	 *  需求:读出所有的记录(Result),然后提取出对应的 age 信息
	 *  
	 *  mapper阶段的  
	 *  
	 *  	输入: 从hbase来
	 *  
	 *  		key :  rowkey     
	 *      	value :  result
	 *      
	 *      	ImmutableBytesWritable, Result
	 *  
	 *      输出: hdfs
	 *      
	 *      	key :  age
	 *          value : 年龄值
	 *          
	 *  reducer阶段:
	 *  
	 *  	输入:
	 *  
	 *      	key :  "age"
	 *          value :    年龄值 = 18
	 *          
	 *     输出:
	 *     
	 *     		key: NullWritbale
	 *     		value: 平均
	 */
	public static class H2H_Mapper extends TableMapper<Text, IntWritable>{
		Text outkey = new Text("age");
		@Override
		protected void map(ImmutableBytesWritable key, Result value,Context context)
				throws IOException, InterruptedException {
			
			boolean containsColumn = value.containsColumn("info".getBytes(), "age".getBytes());
			
			if(containsColumn){
				
				List<Cell> cells = value.getColumnCells("info".getBytes(), "age".getBytes());
				//每次读取一行记录,从这行记录中获取age对应的值,
				Cell cell = cells.get(0);
				
				byte[] cloneValue = CellUtil.cloneValue(cell);
				String age = Bytes.toString(cloneValue);
				
				context.write(outkey, new IntWritable(Integer.parseInt(age)));
			}
			
		}
	}
	
	
	
	public static class H2H_Reducer extends Reducer<Text, IntWritable, Text, DoubleWritable>{
		
		@Override
		protected void reduce(Text key, Iterable<IntWritable> values,Context context)
				throws IOException, InterruptedException {
			int count = 0;
			int sum = 0;
			for (IntWritable iw : values) {
				count ++;
				sum += iw.get();
			}
			
			double avg = sum * 1D / count;
			context.write(key, new DoubleWritable(avg));
		}
		
	}
	
}

### 回答1: 好的,这里是一个简单的 MapReduce 程序的示例代码,用于统计 HBase 的成绩表中的单科排名和总分排名,并将结果上传到 HDFS 。 首先,我们需要导入所需的包: ``` import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Result; 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.hbase.mapreduce.TableMapper; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Reducer; ``` 然后,我们需要定义 Mapper 类和 Reducer 类: Mapper 类: ``` public static class ScoreMapper extends TableMapper<Text, IntWritable> { private static final byte[] CF = "cf".getBytes(); private static final byte[] SUBJECT = "subject".getBytes(); private static final byte[] SCORE = "score".getBytes(); private Text outputKey = new Text(); private IntWritable outputValue = new IntWritable(); @Override public void map(ImmutableBytesWritable row, Result values, Context context) throws IOException, InterruptedException { // 获取科目和成绩 String subject = Bytes.toString(values.getValue(CF, SUBJECT)); int score = Bytes.toInt(values.getValue(CF, SCORE)); // 设置输出键和输出值 outputKey.set(subject); outputValue.set(score); context.write(outputKey, outputValue); } } ``` Reducer 类: ``` public static class ScoreReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable outputValue = new IntWritable(); @Override public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { // 统 ### 回答2: 在MapReduce项目,我们可以使用HBaseHDFS来完成对成绩表的单科排名和总分排名的统计。 首先,我们需要编写MapReduce程序来实现这个目标。我们可以定义两个Mapper任务,一个用于计算单科排名,另一个用于计算总分排名。然后,使用一个Reducer任务将两个排名结果合并,并将结果上传到HDFS。 对于单科排名,我们可以将每一行数据作为输入,并将学生的姓名作为键,成绩作为值。在Mapper任务,我们可以使用Java API查询HBase表,并将学生姓名和成绩作为键值对发送给Reducer任务。在Reducer任务,我们可以根据成绩对学生进行排序,并将结果写入HDFS。 对于总分排名,我们可以将每一行数据作为输入,并将学生的姓名作为键,总分作为值。与单科排名类似,在Mapper任务,我们可以使用Java API查询HBase表,并将学生姓名和总分作为键值对发送给Reducer任务。在Reducer任务,我们可以根据总分对学生进行排序,并将结果写入HDFS。 完成以上步骤后,我们就可以通过运行这个MapReduce程序来实现对HBase成绩表中的单科排名和总分排名的统计。程序会将结果上传到HDFS,可以通过相应的路径访问得到。 注意:在编写MapReduce程序时,需要使用HBase的Java API来连接HBase数据库并进行查询操作。同时,需要使用Hadoop的Java API来连接HDFS并将结果写入HDFS。 希望以上回答对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值