2

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

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

ap

4

1 回答 1

4

知道这可能会令人惊讶,但值 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 跟踪它。

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

编辑:有关其工作方式和原因的一些附加信息:

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

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

在底层,对键和值的引用永远不会改变,每次调用 Iterable.Iterator.next() 都会将底层字节流中的指针指向下一个 KV 对。如果 key grouper 确定当前的 key 字节集合和之前的 set 是比较相同的 key,那么值 Iterable.iterator() 的 hasNext 方法将返回 true,否则返回 false。如果返回 true,则字节将反序列化为 Key 和 Value 实例,以便在您的 reduce 方法中使用。

于 2012-06-26T10:35:58.997 回答