hadoop二次排序一

1.原理

在map阶段的最后,会先调用job.setPartitionerClass对这个List进行分区,每个分区映射到一个reducer。每个分区内又调用job.setSortComparatorClass设置的key比较函数类排序。可以看到,这本身就是一个二次排序。如果没有通过job.setSortComparatorClass设置key比较函数类,则使用key的实现的compareTo方法。
在reduce阶段,reducer接收到所有映射到这个reducer的map输出后,也是会调用job.setSortComparatorClass设置的key比较函数类对所有数据对排序。然后开始构造一个key对应的value迭代器。这时就要用到分组,使用jobjob.setGroupingComparatorClass设置的分组函数类。只要这个比较器比较的两个key相同,他们就属于同一个组,它们的value放在一个value迭代器,而这个迭代器的key使用属于同一个组的所有key的第一个key。最后就是进入Reducer的reduce方法,reduce方法的输入是所有的(key和它的value迭代器)。同样注意输入与输出的类型必须与自定义的Reducer中声明的一致。

2.步骤

(1)自定义key

所有自定义的key应该实现接口WritableComparable,因为是可序列的并且可比较的。并重载方法

@Override
public void write(DataOutput out) {}
    @Override
public void readFields(DataInput in) {}
@Override
public int hashCode() {}
@Override
public boolean equals(Object right) 
@Override
public int compareTo(StringPair o) {}

(2)由于key是自定义的,所以还需要自定义一下类:
(2.1)分区函数类。这是key的第一次比较。

static class FirstPartitioner extends HashPartitioner<StringPair, LongWritable>
在job中使用setPartitionerClasss设置Partitioner。

(2.2)key比较函数类。这是key的第二次比较。这是一个比较器,需要继承WritableComparator。

 public static class SortComparator extends WritableComparator

必须有一个构造函数,并且重载 public int compare(WritableComparable w1, WritableComparable w2)

另一种方法是 实现接口RawComparator。
在job中使用setSortComparatorClass设置key比较函数类。
(2.3)分组函数类。在reduce阶段,构造一个key对应的value迭代器的时候,只要first相同就属于同一个组,放在一个value迭代器。这是一个比较器,需要继承WritableComparator。

  public static class GroupingComparator extends WritableComparator

分组函数类也必须有一个构造函数,并且重载 public int compare(WritableComparable w1, WritableComparable w2)
分组函数类的另一种方法是实现接口RawComparator。
在job中使用setGroupingComparatorClass设置分组函数类。

另外注意的是,如果reduce的输入与输出不是同一种类型,则不要定义Combiner也使用reduce,因为Combiner的输出是reduce的输入。除非重新定义一个Combiner。 

 

  • 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、付费专栏及课程。

余额充值