首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >深入理解hadoop中map阶段的内部工作,减少任务?

深入理解hadoop中map阶段的内部工作,减少任务?
EN

Stack Overflow用户
提问于 2014-07-23 18:13:03
回答 1查看 3K关注 0票数 6

我在读汤姆·怀特的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%)时,后台线程将开始将内容溢出到磁盘。在发生泄漏时,地图输出将继续写入缓冲区,但如果缓冲区在此期间被填满,则映射将被阻塞,直到溢出完成为止。

代码语言:javascript
运行
复制
       _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:

代码语言:javascript
运行
复制
>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目录

代码语言:javascript
运行
复制
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中指定的组合器,则没有应用组合器):

代码语言:javascript
运行
复制
>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段。

如果到目前为止我的理解是正确的,

  1. 如何才能从映射器输出中获得具有分区和排序数据的中间文件。
  2. 有趣的是,仅运行mapper并不会产生排序输出,这与数据发送给还原器没有排序的点相矛盾。More details here
  3. 如果没有只运行Mapper:More details here,甚至不应用任何组合器
EN

Stack Overflow用户

回答已采纳

发布于 2014-07-23 18:30:36

仅映射作业的工作方式与映射和减少作业不同.这并不矛盾,只是不同而已。

如何才能从映射器输出中获得具有分区和排序数据的中间文件。

你不能,没有一个钩子可以从MapReduce的中间阶段获取数据片段。在分区程序之后或在记录读取器之后获取数据也是如此。

有趣的是,仅运行mapper并不会产生排序输出,这与数据发送给还原器没有排序的点相矛盾。这里有更多的细节

这并不矛盾。映射器排序,因为还原器需要排序才能进行合并。如果没有还原器,就没有理由进行排序,所以没有理由进行排序。这是正确的行为,因为我不希望只将其排序在一个映射作业中,这会使我的处理速度变慢。我从来没有过这样的情况,我希望我的地图输出在本地排序。

如果没有只运行Mapper,甚至不应用任何组合器:这里有更多详细信息

组合器是一种优化。不能保证它们确实运行或遍历了哪些数据。组合器的存在主要是为了提高减速器的效率。因此,再一次,就像本地排序一样,如果没有还原器,组合器就不会运行,因为它没有理由运行。

如果您想要类似组合器的行为,我建议将数据写入缓冲区(可能是hashmap),然后在Mapper完成时运行的清理函数中编写本地汇总的数据。如果您想这样做,请注意内存的使用。这是一个更好的方法,因为组合器被指定为一个很好的优化,您不能指望它们运行.即使他们逃跑了。

票数 8
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24917886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档