我了解了在键进入减速器之前对特定键的值进行排序的方式。我了解到可以通过编写三种方法来完成,即 keycomarator、partitioner 和 valuegrouping。
现在,当 valuegrouping 运行时,它基本上对与自然键关联的所有值进行分组,对吗?因此,当它将自然键的所有值分组时,与一组排序值一起发送到减速器的实际键是什么?自然键将与不止一种类型的实体(组合键的第二部分)相关联。发送到 reducer 的复合键是什么?
ap
我了解了在键进入减速器之前对特定键的值进行排序的方式。我了解到可以通过编写三种方法来完成,即 keycomarator、partitioner 和 valuegrouping。
现在,当 valuegrouping 运行时,它基本上对与自然键关联的所有值进行分组,对吗?因此,当它将自然键的所有值分组时,与一组排序值一起发送到减速器的实际键是什么?自然键将与不止一种类型的实体(组合键的第二部分)相关联。发送到 reducer 的复合键是什么?
ap
知道这可能会令人惊讶,但值 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 阶段输出的键/值对:
在底层,对键和值的引用永远不会改变,每次调用 Iterable.Iterator.next() 都会将底层字节流中的指针指向下一个 KV 对。如果 key grouper 确定当前的 key 字节集合和之前的 set 是比较相同的 key,那么值 Iterable.iterator() 的 hasNext 方法将返回 true,否则返回 false。如果返回 true,则字节将反序列化为 Key 和 Value 实例,以便在您的 reduce 方法中使用。