当我使用函数job.setNumReduceTasks(1);
时,我会得到按键排序的输出。然而,当我删除这个函数时,输出并没有按键排序。
那么,当我们有多个减速器任务时,我们是否应该期望从减速器获得排序输出?
谢谢。
输出按单个Reducer中的键排序。然而,默认的Partitioner是散列函数的结果,因此,虽然如果使用多个Reducer,每个文件都会被排序,但一个文件不会是最后一个文件的排序延续。例如:
我们有三个Reducer的单词计数工作。映射器输出:
(A,1)
(zebra,1)
(bat,1)
(zebra,1)
(frog,1)
(A,1)
分区器看起来像下面的
public int getPartition(K key, V value, int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
因此它可以以以下方式分配密钥:
REDUCER 1 REDUCER 2 REDUCER 3
(A,1) (frog,1) (bat,1)
(A,1)
(zebra,1)
请注意,Reducer 1
不包含A-F,Reducer 2
不包含G-M,Reducer 3
不包含N-Z,即不按字母顺序拆分。这就是为什么不会对整体输出进行排序,而是在每个Reducer的输出中对数据进行排序。
这是有道理的,否则我们可能会出现大的偏差。例如,您正在对一些客户服务数据运行MapReduce作业,其中ID总是以C
开头——您不希望所有内容都转到同一个Reducer。