排序—深入了解hadoop中map reduce作业中map阶段的内部工作?

cx6n0qe3  于 2021-06-04  发布在  Hadoop
关注(0)|答案(1)|浏览(377)

我在看书 Hadoop: The definitive guide 3rd edtition 作者:汤姆·怀特。它是了解 Hadoop ,尤其是 Map-Reduce 我很感兴趣。
摘自该书(第205页):
洗牌和排序
mapreduce保证每个reduce的输入都是按键排序的。系统执行排序并将map输出作为输入传输到reducer的过程称为shuffle。
我由此推断,在键被发送到reducer之前,它们是被排序的,这表示作业的map阶段的输出是被排序的。请注意:我不叫它mapper,因为map阶段包括mapper(由程序员编写)和mr框架的内置排序机制。
Map那边
每个map任务都有一个循环内存缓冲区,它将输出写入其中。默认情况下,缓冲区为100 mb,该大小可以通过更改io.sort.mb属性进行调整。当缓冲区的内容达到某个阈值大小(io.sort.spill.percent、默认值0.80或80%)时,后台线程将开始将内容溢出到磁盘。溢出发生时,map输出将继续写入缓冲区,但是如果缓冲区在此期间填满,map将阻塞,直到溢出完成。
在将数据写入磁盘之前,线程首先将数据划分为与最终将发送到的缩减器相对应的分区。在每个分区中,后台线程执行内存中的按键排序,如果有组合器函数,则在排序的输出上运行。运行combiner函数可以获得更紧凑的map输出,因此要写入本地磁盘和传输到reducer的数据更少。
我对以上段落的理解是,当Map器生成键值对时,键值对被划分和排序。一个假设的例子:
考虑将mapper-1用于字数计算程序:

>mapper-1 contents
partition-1
   xxxx: 2
   yyyy: 3
partition-2
   aaaa: 15
   zzzz: 11

(注意,每个分区中的with数据都是按键排序的,但分区1的数据和分区2的数据不必按顺序排序)
继续阅读本章:
每次内存缓冲区达到溢出阈值时,都会创建一个新的溢出文件,因此在map任务写入其最后一个输出记录之后,可能会有几个溢出文件。在任务完成之前,溢出文件将合并到单个分区和排序的输出文件中。配置属性io.sort.factor控制一次合并的最大流数;默认值为10。
我在这里的理解是(请知道上面段落中的粗体短语,这欺骗了我):在一个map任务中,几个文件可能会溢出到磁盘,但它们被合并到一个仍然包含分区和排序的文件中。考虑与上述相同的示例:
在单个Map任务完成之前,其中间数据可以是:
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

map任务完成后,mapper的输出将是一个文件(注意,上面添加了三个spill文件,但假设在job conf中没有指定combiner,则没有应用combiner):

>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段对应的数据被发送到reducer-1,分区2段对应的数据被发送到reducer-2。
如果到目前为止,我的理解是正确的,
如何从Map器输出中获取同时包含分区和排序数据的中间文件。
值得注意的是,单独运行mapper不会产生与发送到reducer的数据未排序的点相矛盾的排序输出。更多详情请点击此处
如果没有运行only mapper,甚至没有应用组合器:更多详细信息请参见此处

lfapxunr

lfapxunr1#

仅Map作业的工作方式与Map和减少作业的工作方式不同。这并不矛盾,只是不同而已。
如何从Map器输出中获取同时包含分区和排序数据的中间文件。
你不能。没有钩子可以从mapreduce的中间阶段获取数据。对于在分区器之后或在记录读取器之后获取数据也是如此。
值得注意的是,单独运行mapper不会产生与发送到reducer的数据未排序的点相矛盾的排序输出。更多详情请点击此处
这并不矛盾。Map器排序是因为reducer需要对其进行排序才能进行合并。如果没有减速机,它就没有理由排序,所以就没有理由排序。这是正确的行为,因为我不希望它在只Map的作业中排序,这会使我的处理速度变慢。我从未遇到过这样的情况,我希望我的Map输出是本地排序。
如果没有运行only mapper,甚至没有应用组合器:更多详细信息请参见此处
组合器是一种优化。无法保证它们实际运行或覆盖了哪些数据。合路器主要是为了使减速器更有效率。所以,同样,就像本地排序一样,如果没有还原器,合并器就不会运行,因为它没有理由这样做。
如果您想要类似于combiner的行为,我建议将数据写入缓冲区(可能是hashmap),然后在Map程序完成时运行的cleanup函数中写出本地汇总的数据。如果要这样做,请注意内存使用。这是一个更好的方法,因为组合器被指定为一个良好的优化,你不能指望他们运行。。。即使他们跑了。

相关问题