Map-Reduce中的二级排序

我理解了在键进入reducer之前对特定键的值进行排序的方法。 我了解到可以通过编写三种方法来完成,即keycomparator,partitioner和valuegrouping。

现在,当值分组运行时,它基本上将与自然键关联的所有值组合在一起,对吗? 因此,当它对自然键的所有值进行分组时,与一组排序值一起发送到reducer的实际键是什么? 自然密钥将与多种类型的实体(复合密钥的第二部分)相关联。 发送到减速机的复合键是什么?

美联社

这可能是令人惊讶的,但Iterable值的每次迭代实际上也更新了关键引用:

protected void reduce(K key, Iterable values, Context context) { for (V value : values) { // key object contents will update for each iteration of this loop } } 

我知道这适用于新的mapreduce API,我还没有为旧的mapred API追踪它。

因此,在回答您的问题时,所有密钥都将可用,第一个密钥将与该组的第一个排序密钥相关。

编辑 :关于其工作原理和原因的一些其他信息:

reducer使用两个比较器来处理map阶段输出的键/值对:

  • 密钥排序比较器 – 首先应用该比较器并命令所有KV对。 从概念上讲,您仍在处理此阶段的序列化字节。
  • 密钥组比较器 – 该比较器负责确定前一个和当前密钥“不同”的时间,表示一组KV对与另一组之间的边界

在引擎盖下,对键和值的引用永远不会改变,每次调用Iterable.Iterator.next()都会将基础字节流中的指针前进到下一个KV对。 如果密钥分组确定当前密钥字节集和先前集合是相对相同的密钥,则值Iterable.iterator()的hasNext方法将返回true,否则返回false。 如果返回true,则将字节反序列化为Key和Value实例,以便在reduce方法中使用。