Reducer可以一次拥有多个键吗?

时间:2014-06-14 18:31:53

标签: hadoop mapreduce mapper reducers

通过mapper,我创建了多个键,然后将它们传递给reducer以执行某些功能。有没有办法可以将多个键一次发送到同一个减速机?实际上我一次需要单个reducer中与键相关的值。提前谢谢!

1 个答案:

答案 0 :(得分:2)

如果您想要的只是将多个键分区到同一个reducer,那么您只需编写一个自定义的Partitioner并为要分区的键生成相同的int。

既然你会意识到分区是不够的,并且你希望一次有多个密钥发送到你的reduce(K k, Iterator<V>),你可能还需要实现一个比较器,使多个密钥比较相等,并将比较器设置为job.setGroupingComparatorClass(GourpingClass.class)

作为Hadoop: The definitive Guide P279的改编示例:

您的数据是这样的:

1990 35  A1 A2 A3 A4
1990 34  B1 B2 B3 B4
1990 34  C2 C2 C3 C4
1991 36  [other data here]
1991 35  [other data here]

如果你想要制作年份&amp;作为地图输出的组合键,并且只将不同年份的键分配给不同的reducer,您只需实现YearPartitioner

public static class YearPartitioner extends Partitioner<CombineKey, V> {
    int getPartition(CombineKey k, V value, int numPartitions) { 
         return k.getyear % numPartitions;
    }
}

并将YearPartitioner设置为job.setPartitionerClass(YearPartitoner.class),通过执行这些操作,您的1990年数据将全部发送到同一个reducer,您的自定义reduce()将首先由<1990,35>调用作为键,<<A1 A2 A3 A4>>作为值列表,并由<1990, 34>再次作为键和<<B1 B2 B3 B4>,<C2 C2 C3 C4>>作为值列表调用。

如果您想进一步将reduce称为<1990,x>作为关键字,<<A1 A2 A3 A4>,<B1 B2 B3 B4>,<C2 C2 C3 C4>>作为值列表,请实施一个关键比较器&amp;将其设置为GroupingComparatorClass