我对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输出没有排序。所以我完全清楚这一点。
我的问题是:
- 映射器的输出总是排序的吗?
- 排序阶段是否已经集成到mapper阶段,使得map阶段的输出已经在中间数据中进行了排序?
- 是否有一种方法从
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