我必须从 n 个候选列表中生成 n*(n-1)/2 个候选对。
这可以在每个 mapper 实例或每个 reducer 实例中完成。
但是我观察到,当这个操作在 Reduce 阶段完成时,它比在 Map 阶段完成的要快得多。是什么原因?
Mappers 可以不支持繁重的计算吗?
Mapper 实例在网络上进行这样的计算有什么影响?
谢谢!
我必须从 n 个候选列表中生成 n*(n-1)/2 个候选对。
这可以在每个 mapper 实例或每个 reducer 实例中完成。
但是我观察到,当这个操作在 Reduce 阶段完成时,它比在 Map 阶段完成的要快得多。是什么原因?
Mappers 可以不支持繁重的计算吗?
Mapper 实例在网络上进行这样的计算有什么影响?
谢谢!
简短的回答是:当使用 mapper 生成数据时,Hadoop 必须将数据从 mapper 复制到 redcuer,这花费了太多时间。
生成的总数据为O(n^2)
。
如果n*(n-1)/2
使用 mapper 生成对,则必须将中间数据复制到 reducer。Hadoop 中的这一步被命名为Shuffle Phase。而reducer 仍然需要将这些数据放到HDFS 中。在 shuffle 阶段从你的原因中的 Harddisk 读取/写入的总数据可以是6* sizeof(intermediate data)
,这是非常大的。
而如果数据是reducer生成的,O(n^2)
则不需要中间数据转换。所以它可以有更好的表现。
所以你的性能问题主要是由数据转换引起的,而不是计算。如果没有磁盘访问,mapper 和 reducer 的性能是一样的。
如果你仍然想使用 mapper 来生成数据,也许io.sort.factor
打开压缩可能有助于提高性能。