hadoop二次排序

package example;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner;

public class SecondSort {
	
	// 假设我们需要对气温记录(key:年份,value:气温)进行排序,要求按年份升序并按气温降序
	// 由于hadoop只会给key排序,并且只能保证每一个reduce收到的数据按key有序
	// 所以需要设置两个方面:1.把key和value拼起来,并且定义为自定义类型对象,保证每个分区内按自定义排序规则有序
	// 这种组合key虽然保证了分区内有序,但也由于组合键的原因,无法保证同个年份在同个分区(1970+30C°和1970+31C°显然不是相同的key,而hadoop只会将相同的key传到同一个reducer)
	// 2.为了保证全局有序,把reduce的数量设为1
	
	// 首先编写组合键的类型,集成Writable接口和Comparable接口,并重写compareTo方法
	public class CombineKey implements WritableComparable<CombineKey>{

		private Text year;
		private IntWritable temperature;
		
		public CombineKey(Text year, IntWritable temperature){
			this.year = year;
			this.temperature = temperature;
		}
		@Override
		public void readFields(DataInput arg0) throws IOException {
			// TODO Auto-generated method stub
			year.readFields(arg0);
			temperature.readFields(arg0);
		}

		@Override
		public void write(DataOutput arg0) throws IOException {
			// TODO Auto-generated method stub
			year.write(arg0);
			temperature.write(arg0);
		}

		// 按value升序排序,分区的时候再按year分区
		@Override
		public int compareTo(CombineKey combineKey) {
			// TODO Auto-generated method stub
			return temperature.get() - combineKey.temperature.get();
		}
		
		public Text getYear(){
			return year;
		}
	}
	
	public class KeyPartioner extends Partitioner<CombineKey, IntWritable>{

		@Override
		public int getPartition(CombineKey arg0, IntWritable arg1, int arg2) {
			// TODO Auto-generated method stub
			return new HashPartitioner().getPartition(arg0.getYear(), arg1, arg2);
		}
		
	}
	
	public static void main(String args[]) throws IOException, ClassNotFoundException, InterruptedException{
		// 省略mapper和reducer以及输入输出格式、路径的设置
		Job job = new Job();
		job.setJarByClass(SecondSort.class);
		job.setMapOutputKeyClass(CombineKey.class);
		job.setPartitionerClass(KeyPartioner.class);
		
		job.waitForCompletion(true);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用MapReduce框架来实现Hadoop工程关于温度的二次排序程序。具体实现方法如下: 1. Mapper阶段:将输入的数据按照温度值和时间戳进行分割,将温度值作为Key,将时间戳和温度值作为Value输出。 2. Shuffle阶段:将Mapper输出的Key-Value对按照Key进行排序,将相同Key的Value放在同一个Reducer中处理。 3. Reducer阶段:将Mapper输出的Value按照时间戳进行排序,将排序后的结果输出。 下面是一个简单的Hadoop工程关于温度的二次排序程序的代码示例: Mapper代码: public class TemperatureMapper extends Mapper<LongWritable, Text, IntWritable, Text> { private IntWritable temperature = new IntWritable(); private Text timeAndTemperature = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String[] tokens = value.toString().split(","); int temp = Integer.parseInt(tokens[1]); temperature.set(temp); timeAndTemperature.set(tokens[0] + "," + tokens[1]); context.write(temperature, timeAndTemperature); } } Reducer代码: public class TemperatureReducer extends Reducer<IntWritable, Text, Text, IntWritable> { private Text time = new Text(); public void reduce(IntWritable key, Iterable<Text> values, Context context) throws IOException, InterruptedException { for (Text value : values) { String[] tokens = value.toString().split(","); time.set(tokens[0]); context.write(time, key); } } } 注意:以上代码仅供参考,实际应用中需要根据具体情况进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值