Map-Reduce 中的二次排序



我了解在键进入化简器之前对特定键的值进行排序的方法。我了解到这可以通过编写三种方法来完成,即键比较器、分区器和值分组。

现在,当值分组

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

美联社

知道这一点可能令人惊讶,但值 Iterable 的每次迭代实际上也会更新键引用:

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

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

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

编辑:关于如何以及为什么工作的一些附加信息:

化简器使用两个比较器来处理映射阶段输出的键/值对:

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

在后台,对键和值的引用永远不会改变,每次调用 Iterable.Iterator.next() 都会将底层字节流中的指针推进到下一个 KV 对。如果键分组程序确定当前键字节集和上一组键相对相同,则值 Iterable.iterator() 的 hasNext 方法将返回 true,否则返回 false。如果返回 true,则字节将反序列化为键和值实例,以便在 reduce 方法中使用。

最新更新