我对从Mapper获得的输出有点困惑.
例如,当我运行一个简单的wordcount程序时,使用此输入文本:
hello world Hadoop programming mapreduce wordcount lets see if this works 12345678 hello world mapreduce wordcount
这是我得到的输出:
12345678 1 Hadoop 1 hello 1 hello 1 if 1 lets 1 mapreduce 1 mapreduce 1 programming 1 see 1 this 1 wordcount 1 wordcount 1 works 1 world 1 world 1
如您所见,mapper的输出已经排序.我根本没跑Reducer
.但我发现在另一个项目中,mapper的输出没有排序.所以我对此完全清楚..
我的问题是:
映射器的输出总是排序吗?
排序阶段是否已经集成到映射器阶段,以便映射阶段的输出已经在中间数据中排序?
有没有办法从sort and shuffle
阶段收集数据并在它进入Reducer之前保留它?减速器带有一个键和一个迭代列表.有没有办法,我可以保留这些数据吗?
vefthym.. 8
映射器的输出总是排序吗?
不.如果您不使用减速机,则不会进行分类.如果使用reducer,则在将映射器的输出写入磁盘之前会有一个预排序过程.数据在Reduce阶段进行排序.这里发生的事情(只是一个猜测)是你没有指定一个Reducer类,它在新的API中被转换为使用Identity Reducer(参见这个答案和注释).Identity Reducer只输出其输入.要验证这一点,请参阅默认的Reducer计数器(应该有一些reduce任务,减少输入记录和组,减少输出记录......)
排序阶段是否已经集成到映射器阶段,以便映射阶段的输出已经在中间数据中排序?
正如我在上一个问题中解释的那样,如果你不使用reducer,mapper不会对数据进行排序.如果使用reducers,数据将从map阶段开始排序,然后在reduce阶段进行合并排序.
有没有办法从排序和随机播放阶段收集数据并在它转到Reducer之前保留它.减速器带有一个键和一个迭代列表.有没有办法,我可以保留这些数据吗?
同样,改组和排序是Reduce阶段的一部分.身份减少器会做你想要的.如果要为每个reducer输出一个键值对,并且值是迭代的串联,只需将迭代存储在内存中(例如,在StringBuffer中),然后将此并置作为值输出.如果您希望地图输出直接进入程序的输出,而不经过reduce阶段,那么在驱动程序类中将reduce任务的数量设置为零,如下所示:
job.setNumReduceTasks(0);
但是,这不会使您的输出排序.它将跳过映射器的预排序过程并将输出直接写入HDFS.