我在读汤姆·怀特的Hadoop: The definitive guide 3rd edtition
。对于理解Hadoop
的内部结构,特别是我感兴趣的Map-Reduce
,它是一个极好的资源。
这本书(第205页):
洗牌和排序
MapReduce保证每个减速器的输入按键排序。系统执行排序的过程--并将映射输出作为输入传递到减速机--被称为洗牌。
我由此推断,在键被发送到还原器之前,它们是排序的,这意味着任务映射阶段的输出是排序的。请注意:我不称它为mapper,因为映射阶段包括mapper (由程序员编写)和内置的MR框架排序机制。
地图侧
每个映射任务都有一个循环内存缓冲区,它将输出写入该缓冲区。默认情况下,缓冲区为100 MB,可以通过更改io.sort.mb属性来调整大小。当缓冲区的内容达到一定的阈值大小(io.sort.spill.per分号、默认值0.80或80%)时,后台线程将开始将内容溢出到磁盘。在发生泄漏时,地图输出将继续写入缓冲区,但如果缓冲区在此期间被填满,则映射将被阻塞,直到溢出完成为止。
_Before it writes to disk, the thread first divides the data into_ _**partitions corresponding to the reducers**_ _that they will ultimately be sent to. Within each partition, the back- ground thread performs an in-memory sort by key, and if there is a combiner function, it is run on the output of the sort. Running the combiner function makes for a more compact map output, so there is less data to write to local disk and to transfer to the reducer._
我对以上段落的理解是,由于映射器生成密钥-值对,因此对键-值对进行了分区和排序。一个假设的例子:
考虑一个单词计数程序的mapper-1:
>mapper-1 contents
partition-1
xxxx: 2
yyyy: 3
partition-2
aaaa: 15
zzzz: 11
(注:在每个分区数据中,按键排序,但分区-1的数据和分区-2的数据必须按照顺序排列是不必要的)
继续阅读本章:
每次内存缓冲区到达溢出阈值时,都会创建一个新的溢出文件,因此在map任务写入其最后一个输出记录后,可能会有几个溢出文件。在任务完成之前,溢出文件被合并到一个单个分区输出文件__中。configuration属性io.sort.factor控制要一次合并的最大流数;默认值为10。
我在这里的理解是(请知道上段中的粗体短语,它欺骗了我):在一个映射任务中,可能会有几个文件溢出到磁盘上,但是它们合并到一个仍然包含分区并被排序的文件中。考虑与上面相同的例子:
在完成单个地图任务之前,其中间数据可能是:
mapper-1目录
spill 1: spill 2: spill 2:
partition-1 partition-1 partition-1
hhhh:5
xxxx: 2 xxxx: 3 mmmm: 2
yyyy: 3 yyyy: 7 yyyy: 9
partition-2 partition-2 partition-2
aaaa: 15 bbbb: 15 cccc: 15
zzzz: 10 zzzz: 15 zzzz: 13
完成映射任务后,mapper的输出将是一个文件(注意上面的三个溢出文件现在被添加,但如果没有在作业conf中指定的组合器,则没有应用组合器):
>Mapper-1 contents:
partition-1:
hhhh: 5
mmmm: 2
xxxx: 2
xxxx: 3
yyyy: 3
yyyy: 7
yyyy: 9
partition-2:
aaaa: 15
bbbb: 15
cccc: 15
zzzz: 10
zzzz: 15
zzzz: 13
在这里,分区-1可能对应于减速器-1。也就是说,上面的数据对应部分-1段被发送到减速器-1,而对应于分区-2段的数据被发送给减速器-2段。
如果到目前为止我的理解是正确的,
发布于 2014-07-23 18:30:36
仅映射作业的工作方式与映射和减少作业不同.这并不矛盾,只是不同而已。
如何才能从映射器输出中获得具有分区和排序数据的中间文件。
你不能,没有一个钩子可以从MapReduce的中间阶段获取数据片段。在分区程序之后或在记录读取器之后获取数据也是如此。
有趣的是,仅运行mapper并不会产生排序输出,这与数据发送给还原器没有排序的点相矛盾。这里有更多的细节
这并不矛盾。映射器排序,因为还原器需要排序才能进行合并。如果没有还原器,就没有理由进行排序,所以没有理由进行排序。这是正确的行为,因为我不希望只将其排序在一个映射作业中,这会使我的处理速度变慢。我从来没有过这样的情况,我希望我的地图输出在本地排序。
如果没有只运行Mapper,甚至不应用任何组合器:这里有更多详细信息
组合器是一种优化。不能保证它们确实运行或遍历了哪些数据。组合器的存在主要是为了提高减速器的效率。因此,再一次,就像本地排序一样,如果没有还原器,组合器就不会运行,因为它没有理由运行。
如果您想要类似组合器的行为,我建议将数据写入缓冲区(可能是hashmap),然后在Mapper完成时运行的清理函数中编写本地汇总的数据。如果您想这样做,请注意内存的使用。这是一个更好的方法,因为组合器被指定为一个很好的优化,您不能指望它们运行.即使他们逃跑了。
https://stackoverflow.com/questions/24917886
复制相似问题