知道这可能令人惊讶,但是值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进行追踪。
因此,在回答您的问题时,所有键都将可用,第一个键将与组中的第一个排序键相关。
编辑 :有关如何以及为什么这样工作的一些其他信息:
归约器使用两个比较器来处理map阶段输出的键/值对:
- 密钥排序比较器-首先应用此比较器,并对所有KV对进行排序。从概念上讲,您仍在此阶段处理序列化的字节。
- 密钥组比较器-该比较器负责确定上一个密钥和当前密钥何时“不同”,表示一组KV对与另一对KV对之间的边界
在幕后,对键和值的引用永远不会改变,每次对Iterable.Iterator.next()的调用都会将基础字节流中的指针前进到下一个KV对。如果密钥分组程序确定当前密钥字节集和先前密钥字节集是相对相同的密钥,则Iterable.iterator()值的hasNext方法将返回true,否则返回false。如果返回true,则将字节反序列化为Key和Value实例,以供您的reduce方法使用。



