Map-Reduce中的二级排序
我了解在密钥进入化简器之前对特定密钥的值进行排序的方式。我了解到,可以通过编写三种方法来完成此工作,即键比较器,分区器和值分组。
现在,当值分组运行时,它基本上将与自然键关联的所有值分组,对吗?因此,当它对自然键的所有值进行分组时,将与一组排序后的值一起发送给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进行追踪。
因此,在回答您的问题时,所有键都将可用,第一个键将与组中的第一个排序键相关。
编辑 :有关如何以及为什么这样工作的一些其他信息:
归约器使用两个比较器来处理map阶段输出的键/值对:
- 密钥排序比较器-首先应用此比较器,并对所有KV对进行排序。从概念上讲,您仍在此阶段处理序列化的字节。
- 密钥组比较器-该比较器负责确定上一个密钥和当前密钥何时“不同”,表示一组KV对与另一对KV对之间的边界
在幕后,对键和值的引用永远不会改变,每次对Iterable.Iterator.next()的调用都会将基础字节流中的指针前进到下一个KV对。如果密钥分组程序确定当前密钥字节集和先前密钥字节集是相对相同的密钥,则Iterable.iterator()值的hasNext方法将返回true,否则返回false。如果返回true,则将字节反序列化为Key和Value实例,以供您的reduce方法使用。