mapreduce作业的map阶段输出总是排序?

时间:2014-07-16 01:54:33

标签: hadoop mapreduce hadoop2

我对从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的输出没有排序。 所以我对此完全清楚..

我的问题是:

  1. 映射器的输出是否始终排序?
  2. 排序阶段是否已经集成到映射器阶段,因此映射阶段的输出已经在中间数据中排序了?
  3. 有没有办法从sort and shuffle阶段收集数据并在它进入Reducer之前保留它?减速器带有一个键和一个迭代列表。有没有办法,我可以保留这些数据吗?

5 个答案:

答案 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已经回答

  • 标题##排序阶段是否已经与mapper阶段集成,因此map阶段的输出已经在中间数据中排序了?

    在Mapreduce作业中,如您所知,Mapper运行单独的数据拆分和数据持久的节点。 Mapper的结果在写入下一阶段之前写成TEMPORARILY。

  • 对于reduce操作,TEMPORARILY存储的Mapper输出在移动到reduce操作之前根据分区程序需要进行排序和随机播放

  • 对于Map Only Job,就像你的情况一样,暂时存储的Mapper输出根据键排序并写入最终输出文件夹(在Job的参数中指定)。

  • 标题##有没有办法从排序和随机播放阶段收集数据,并在转到Reducer之前保留它。减速器带有一个键和一个迭代列表。有没有办法,我可以保留这些数据吗?

    不确定您的要求是什么。使用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:

identityreducer in the new Hadoop API