【问题标题】:using a reducer slows the mapper使用减速器会减慢映射器的速度
【发布时间】:2014-09-20 15:35:27
【问题描述】:

当我将 reducer 的数量设置为零时,map 阶段完成得非常快(约 10 分钟)。 但是,当我将 reducer 的数量设置为大于 1 时,map 阶段所需的时间(完全相同的 mapper 代码)会急剧增加(我在大约 30 分钟后停止它,而它仍然是 20%)。队列中的第一个map任务达到100%,然后进程卡住了。

任何直觉?是不是在不使用reducer时map输出直接到磁盘,而在使用reduce阶段时map输出到内存缓冲区?

我的主映射器循环的伪代码如下:

for (VIntWritable e1 : D2entities) {                    
    for (VIntWritable e1 : D1entities) {    
       output.collect(e1, e2);
    }           
}

在这两种情况下,我都使用conf.setCompressMapOutput(true)conf.set("mapred.reduce.slowstart.completed.maps", "1.00");。当我使用reducer时,我也设置了:

conf.setOutputKeyClass(VIntWritable.class);     
conf.setOutputValueClass(NullWritable.class);       

conf.setMapOutputKeyClass(VIntWritable.class);
conf.setMapOutputValueClass(VIntWritable.class);

否则,我使用:

conf.setOutputKeyClass(VIntWritable.class);     
conf.setOutputValueClass(VIntWritable.class);

【问题讨论】:

    标签: hadoop io mapreduce


    【解决方案1】:

    当您将 reducer 的数量设置为 0 时,您正在执行仅映射的工作。这意味着数据不会被排序或打乱,映射器的输出将直接写入磁盘。但是,如果你使用reducer,那么你有两种情况:当你只需要对数据进行排序时,以及当你还需要对数据进行一些聚合或一些操作时。

    如果您只需要对数据进行排序,您可以使用身份归约器,它将对数据进行排序,执行 shuffle,将其提供给归约器,然后将其写入磁盘。在第二种情况下,reducer 需要额外的时间来执行您希望执行的操作,无论是聚合还是其他任何事情。

    所以是的,只做一个 map 的工作和写一个 reduce 阶段的时间有很大的不同。考虑下图,如果在映射之后直接将其写入磁盘,则所有步骤都不必经过:

    编辑:在添加减少阶段时,您会看到映射器达到 100%,但由于效率原因在映射阶段进行了一些预排序,因此不会显示为已完成,这也使得一些缓冲写入内存。因此,当您仅将工作编写为地图时,这并没有完成,并且完成得更快。但是,既然您还使用了 reducer,一旦达到 mapper 的 100%,它就会开始在内存中进行预排序和缓冲,并且在完成之前不会显示为“Completed”。

    希望现在更清楚了!

    【讨论】:

    • 我同意。不过,我的问题是,当我将 reducer 的数量设置为大于零时,在 reduce 阶段开始之前,相同的 map 任务花费的时间太长了!比如说,我有 250 个映射器在队列中,其中 50 个同时运行。当这些达到 100% 时,它们甚至都没有获得“完成”状态。
    • 哦,好的,现在我更好地理解了您的问题,对此感到抱歉。请查看我的编辑。
    • 是的,现在清楚多了,谢谢!我会稍等片刻才接受你的回答
    • 很高兴它对您有所帮助!
    猜你喜欢
    • 2010-10-23
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多