我对从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之前保留它?减速器带有一个键和一个迭代列表。有没有办法,我可以保留这些数据吗?答案 0 :(得分:8)
映射器的输出是否始终排序?
没有。如果您不使用减速器,则不会进行排序。如果使用reducer,则在将映射器的输出写入磁盘之前会有一个预排序过程。数据在Reduce阶段进行排序。这里发生的事情(只是一个猜测)是你没有指定一个Reducer类,它在新的API中被转换为使用Identity Reducer(参见this answer和注释)。 Identity Reducer只输出其输入。要验证这一点,请参阅默认的Reducer计数器(应该有一些reduce任务,减少输入记录和组,减少输出记录......)
排序阶段是否已经集成到映射器阶段,因此映射阶段的输出已经在中间数据中排序了?
正如我在上一个问题中所解释的,如果您不使用reducer,则mapper不会对数据进行排序。如果确实使用了reducers,数据将从map阶段开始排序,然后在reduce阶段进行合并排序。
有没有办法从sort和shuffle阶段收集数据并在它转到Reducer之前保留它。减速器带有一个键和一个迭代列表。有没有办法,我可以保留这些数据吗?
同样,改组和排序是Reduce阶段的一部分。身份减少器将执行您想要的操作。如果要为每个reducer输出一个键值对,并且值是迭代的串联,只需将迭代存储在内存中(例如在StringBuffer中),然后将此串联作为值输出。如果您希望地图输出直接进入程序的输出,而不经过减少阶段,那么在驱动程序类中将reduce任务的数量设置为零,如下所示:
job.setNumReduceTasks(0);
但这不会使您的输出排序。它将跳过映射器的预排序过程并将输出直接写入HDFS。
答案 1 :(得分:0)
第1点:mapper的输出始终排序,但基于Key。
即如果Map方法执行此操作:context.write(outKey, outValue);
则结果将根据outKey
进行排序。
答案 2 :(得分:0)
以下是您的问题的一些解释
@SurJanSR已经回答
在Mapreduce作业中,如您所知,Mapper运行单独的数据拆分和数据持久的节点。 Mapper的结果在写入下一阶段之前写成TEMPORARILY。
对于reduce操作,TEMPORARILY存储的Mapper输出在移动到reduce操作之前根据分区程序需要进行排序和随机播放
对于Map Only Job,就像你的情况一样,暂时存储的Mapper输出根据键排序并写入最终输出文件夹(在Job的参数中指定)。
不确定您的要求是什么。使用IdentityReducer只会保留输出。我不确定这是否能回答你的问题。
答案 3 :(得分:0)
我支持vefthym的答案。 通常 Mapper输出在将其本地存储在节点上之前进行排序。但是当您在作业配置中明确地将numReduceTasks设置为0时,映射器o / p将不会被排序并直接写入HDFS。 所以我们不能说Mapper输出总是排序!
答案 4 :(得分:0)
<强> 1。映射器的输出是否始终排序?
2.排序阶段是否已经集成到映射器阶段,因此映射阶段的输出已经在中间数据中排序了?
来自Apache MapReduceTutorial:
(在Mapper
部分下)
随后,与给定输出键关联的所有中间值都按框架分组,并传递给Reducer以确定最终输出。
对Mapper输出进行排序,然后根据Reducer进行分区 。分区总数与作业的reduce任务数相同
(在Reducer
部分下)
Reducer NONE
如果不需要减少,将减少任务的数量设置为零是合法的。
在这种情况下,map-tasks的输出直接进入FileSystem,进入FileOutputFormat.setOutputPath(Job,Path)设置的输出路径。 框架不会在将地图输出写入文件系统之前对其进行排序。
<强> 3。有没有办法从sort和shuffle阶段收集数据并在它进入Reducer之前保留它?减速器带有一个键和一个迭代列表。有没有办法,我可以保留这些数据吗?
我不这么认为。来自Apache Reducer的谴责:
Reducer有3个主要阶段:
<强> 随机: 强>
Reducer通过网络使用HTTP复制每个Mapper的排序输出。
<强> 类别: 强> 框架合并按键对Reducer输入进行排序(因为不同的Mapper可能输出相同的键)。
混洗和排序阶段同时发生,即在提取输出时,它们会合并。
<强> 减少 强>
reduce任务的输出通常通过RecordWriter
写入TaskInputOutputContext.write(Object, Object)
。
Reducer的输出不会重新排序。
根据文档,shuffle和sort阶段由框架
驱动如果要保留数据,请将Reducer的数量设置为Zero,这会导致Map输出持久存储到HDFS,但不会对数据进行排序。
看看相关的SE问题:
hadoop: difference between 0 reducer and identity reducer?
我在Hadoop 2.x版本中找不到IdentityReducer: