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);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值