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



我对Mapper的输出有点困惑。

例如,当我运行一个简单的单词计数程序时,输入文本为:

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. 排序阶段是否已经集成到mapper阶段,使得map阶段的输出已经在中间数据中进行了排序?
  2. 是否有一种方法从sort and shuffle阶段收集数据并在它去到Reducer之前持久化它?一个减速器用一个键和一个可迭代对象列表表示。有没有办法,我可以保存这些数据?

映射器的输出总是排序的吗?

。如果不使用减速器,则不排序。如果使用减速器,则在将映射器的输出写入磁盘之前会有一个预排序过程。数据在Reduce阶段进行排序。这里发生的事情(只是猜测)是您没有指定一个Reducer类,在新的API中,它被转换为使用Identity Reducer(请参阅此回答和注释)。恒等减速器只输出它的输入。要验证这一点,请查看默认的Reducer计数器(应该有一些reduce任务,reduce输入记录&组,减少输出记录…)

排序阶段是否已经集成到mapper阶段,使得map阶段的输出已经在中间数据中排序?

正如我在上一个问题中解释的那样,如果不使用reducer, mapper不会对数据进行排序。如果使用reducer,则从map阶段开始对数据进行排序,然后在reduce阶段进行合并排序。

是否有一种方法从排序和洗牌阶段收集数据,并在它进入Reducer之前持久化它。一个减速器用一个键和一个可迭代对象列表表示。有没有办法,我可以保存这些数据?

同样,洗牌和排序是Reduce阶段的一部分。恒等减速器会做你想做的事情。如果你想在每个reducer中输出一个键值对,并且这些值是可迭代对象的一个连接,那么只需将可迭代对象存储在内存中(例如在StringBuffer中),然后将这个连接作为一个值输出。如果您希望映射输出直接到程序的输出,而不经过reduce阶段,那么在驱动程序类中将reduce任务的数量设置为零,如下所示:

job.setNumReduceTasks(0);
但是,

这不会使您的输出排序。它将跳过映射器的预排序过程,直接将输出写入HDFS。

第一点:从mapper的输出总是排序,但基于键。例如,如果Map方法是这样做的:context.write(outKey, outValue);,那么结果将基于outKey排序

以下是对您的问题的一些解释

  • 标题##从mapper输出总是排序吗?

    @SurJanSR已经回复

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

    在Mapreduce作业中,如您所知,Mapper运行在数据的单个拆分和数据持久化的节点上。Mapper的结果在写入下一阶段之前被临时写入。

  • 在reduce操作的情况下,临时存储的Mapper输出被排序,根据分区者的需要进行shuffle,然后移动到reduce操作

  • 在Map Only Job的情况下,与您的情况一样,临时存储的Mapper输出将根据键排序并写入最终输出文件夹(如作业的参数中指定的那样)。

  • 标题##是否有一种方法可以从排序和洗牌阶段收集数据并在它进入Reducer之前持久化它?一个减速器用一个键和一个可迭代对象列表表示。有没有办法,我可以保存这些数据?

    不确定你的需求是什么。使用IdentityReducer只会持久化输出。我不确定这是否回答了你的问题

支持vefthym的答案。通常 Mapper输出在本地存储到节点之前是排序的。但是当你在作业配置中显式地将numReduceTasks设置为0时,映射器o/p将不会被排序并直接写入HDFS。所以我们不能说Mapper输出总是排序!

映射器的输出总是排序的吗?

2。排序阶段是否已经集成到映射阶段,以便映射阶段的输出已经在中间数据中排序?

From Apache MapReduceTutorial:

(Mapper节下)

与给定输出键相关联的所有中间值随后由框架分组,并传递给Reducer以确定最终输出。

Mapper输出被排序,然后按照Reducer 进行分区。分区总数与作业

的reduce任务数相同。

(Reducer节下)

减速机没有

如果不需要reduce,可以将reduce-task的个数设置为0。

在本例中,map-tasks的输出直接进入FileOutputFormat设置的输出路径。setOutputPath(工作、路径)。框架在将映射输出写入文件系统之前不会对它们进行排序。

3。是否有一种方法从排序和洗牌阶段收集数据,并在它去到Reducer之前持久化它?一个减速器用一个键和一个可迭代对象列表表示。有没有办法,我可以保存这些数据?

我不这么认为。

减速机有3个初级阶段:

洗牌:

Reducer通过网络使用HTTP从每个Mapper复制排序后的输出。

: 框架按键对Reducer的输入进行归并排序(因为不同的映射器可能输出相同的键)。

shuffle和sort阶段同时发生,即当输出被提取时,它们被合并。

减少:

reduce任务的输出通常通过TaskInputOutputContext.write(Object, Object)写入RecordWriter

Reducer的输出没有重新排序。

根据文档,洗牌和排序阶段由框架

驱动

如果你想持久化数据,将reduce的number设置为0,这会导致Map输出持久化到HDFS,但它不会对数据进行排序。

查看相关SE问题:

hadoop: 0 reducer和identity reducer的区别?

我没有在Hadoop 2中找到IdentityReducer。x版本:

identityreducer在新的Hadoop API


相关内容

  • 没有找到相关文章

最新更新