我对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之前将其持久化?会向还原器提供一个键和一个可迭代列表。有没有办法,我可以持久化这些数据?
映射器的输出是否始终排序?
不。如果你不使用还原器,它就不会排序。如果你使用还原器,在映射器的输出写入磁盘之前有一个预排序过程。数据在还原阶段被排序。这里发生的事情(只是一个猜测)是你没有指定一个还原器类,在新的API中,它被翻译成使用身份还原器(参见这个答案和评论)。身份还原器只是输出它的输入。要验证这一点,请参阅默认的还原器计数器(应该有一些还原任务,减少输入记录
排序阶段是否已经集成到映射器阶段,以便映射阶段的输出已经在中间数据中排序?
正如我在上一个问题中解释的那样,如果您不使用还原器,mapper不会对数据进行排序。如果您确实使用了还原器,则数据从映射阶段开始排序,然后在还原阶段进行合并排序。
有没有一种方法可以从sort和shuffle阶段收集数据并在它进入Reducer之前将其持久化。一个还原器会显示一个键和一个可迭代列表。有没有办法,我可以持久化这些数据?
同样,混洗和排序是Reduce阶段的一部分。身份减少器会做你想做的事情。如果你想为每个减少器输出一个键值对,这些值是可迭代对象的连接,只需将可迭代对象存储在内存中(例如在StringBuffer中),然后将此连接作为值输出。如果你想让映射输出直接到达程序的输出,而不经过减少阶段,那么在驱动程序类中将减少任务的数量设置为零,如下所示:
job.setNumReduceTasks(0);
但是,这不会对输出进行排序。它将跳过映射器的预排序过程,并将输出直接写入HDFS。
第1点:映射器的输出始终排序,但基于Key。即如果Map方法这样做:context. write(outKey,outValue);
然后结果将根据outKey
进行排序。
以下是对你的问题的一些解释
>
已经由@SurJanSR回答
如您所知,在Mapduce Job中,Mapper在数据的单独拆分和数据持久化的节点上运行。Mapper的结果在写入下一阶段之前被临时写入。
在减少操作的情况下,临时存储的Mapper输出被排序,在移动到减少操作之前根据分区器的需要进行混洗
在Map Only Job的情况下,与您的情况一样,临时存储的Mapper输出根据键进行排序并写入最终输出文件夹(在Job的参数中指定)。
不确定您的要求是什么。使用IdtyReducer只会持久化输出。我不确定这是否回答了您的问题。