6

我对从 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。但是我在另一个项目中发现映射器的输出没有排序。所以我完全清楚这一点..

我的问题是:

  1. 映射器的输出是否总是排序的?
  2. 排序阶段是否已经集成到映射器阶段,以便映射阶段的输出已经在中间数据中排序?
  3. 有没有办法从sort and shuffle阶段收集数据并在它进入减速器之前将其持久化?一个reducer 带有一个key 和一个iterables 列表。有没有办法,我可以保留这些数据?
4

5 回答 5

9

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

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

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

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

有没有办法从排序和洗牌阶段收集数据并在它进入 Reducer 之前将其持久化。一个reducer 带有一个key 和一个iterables 列表。有没有办法,我可以保留这些数据?

同样,洗牌和排序是归约阶段的一部分。Identity Reducer 会做你想做的事。如果你想为每个reducer 输出一个键值对,并且值是iterables 的串联,只需将iterables 存储在内存中(例如,在StringBuffer 中),然后将此串联作为值输出。如果您希望 map 输出直接进入程序的输出,而不经过 reduce 阶段,则在驱动程序类中将 reduce 任务的数量设置为零,如下所示:

job.setNumReduceTasks(0);

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

于 2014-07-17T08:22:20.300 回答
0

第 1 点:mapper 的输出总是按 Key 排序的。即,如果 Map 方法正在这样做:context.write(outKey, outValue);那么结果将基于outKey.

于 2014-07-16T07:04:27.820 回答
0

以下将对您的问题进行一些解释

  • 标题 ##mapper 的输出是否总是排序的?

    @SurJanSR 已经回答了

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

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

  • 在reduce操作的情况下,临时存储的Mapper输出被排序,在移动到reduce操作之前根据partitioner的需要进行shuffle

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

  • Heading ##有没有办法从排序和洗牌阶段收集数据,并在它进入 Reducer 之前将其持久化。一个reducer 带有一个key 和一个iterables 列表。有没有办法,我可以保留这些数据?

    不确定你的要求是什么。使用 IdentityReducer 只会保留输出。我不确定这是否能回答你的问题。

于 2014-07-16T19:44:13.713 回答
0

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

于 2016-05-22T00:27:50.347 回答
0

1、mapper的输出总是排序的吗?

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

来自 Apache MapReduceTutorial

(下Mapper节)

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

Mapper 输出经过排序,然后按 Reducer 进行分区。分区总数与作业的reduce任务数相同

(下Reducer节)

减速机 NONE

如果不需要减少,将减少任务的数量设置为零是合法的。

在这种情况下,映射任务的输出直接进入文件系统,进入由 FileOutputFormat.setOutputPath(Job, Path) 设置的输出路径。在将映射输出写入文件系统之前,框架不会对它们进行排序。

3. 有没有办法从排序和洗牌阶段收集数据并在进入Reducer之前将其持久化?一个reducer 带有一个key 和一个iterables 列表。有没有办法,我可以保留这些数据?

我不这么认为。来自 Apache 对Reducer的谴责:

Reducer 有 3 个主要阶段:

随机播放:

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

排序: 框架通过键对Reducer 输入进行合并排序(因为不同的Mapper 可能输出相同的键)。

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

减少:

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

Reducer 的输出不会重新排序。

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

如果要持久化数据,请将 reducer 的数量设置为零,这会导致 Map 输出持久化到 HDFS 中,但不会对数据进行排序。

看看相关的 SE 问题:

hadoop:0 reducer 和 identity reducer 的区别?

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

新 Hadoop API 中的identityreducer


于 2016-05-22T08:53:27.947 回答