为什么我们需要"地图"部分在MapReduce?

时间:2015-11-03 20:39:45

标签: hadoop mapreduce apache-spark functional-programming

编程模型MapReduce由2个程序组成,map和reduce。当我们可以简单地在reduce函数内部进行映射时,为什么我们需要map部分。

考虑以下伪代码:

result = my_list.map(my_mapper).reduce(my_reducer);

这可以缩短为

result = my_list.reduce(lambda x : my_reducer(my_mapper(x)));

第一种方法如何比第二种方法更优先,而第一种方法需要再通过一次数据?我的代码示例是否过于简单化了?

2 个答案:

答案 0 :(得分:4)

好吧,如果你引用Hadoop样式MapReduce,它实际上是map-shuffle-reduce,其中shuffle是map和reduce分离的原因。稍微高一点,你可以考虑数据的位置。通过map传递的每个键值对可以生成零个或多个键值对。为了能够减少这些,您必须确保给定键的所有值都可以在单个reduce上使用,因此可以进行随机播放。从单个输入对发出的重要对可以由不同的减速器处理。

可以使用地图侧聚合或组合器等模式,但在一天结束时它仍然是(map)-reduce-shuffle-reduce。

假设数据局部性不是问题,像map和reduce这样的高阶函数提供了一个优雅的抽象层。最后,它是一个声明性API。像xs.map(f1).reduce(f2)这样的简单表达只描述 。根据语言或上下文的不同,可以对这些操作进行热切或懒惰的评估,在更复杂的情况下,可以通过多种方式重新排序和优化操作。

关于你的代码。即使签名是正确的,也不会真正减少传递数据的次数。此外,如果将map推送到聚合,则传递给聚合函数的参数不再是同一类型。它意味着顺序折叠或更复杂的合并逻辑。

答案 1 :(得分:1)

在较高的层面上,map reduce是关于并行处理的。尽管减速器在地图输出上工作,但实际上,每个减速器只能获得部分数据,而这只能在第一种方法中实现。

在你的第二种方法中,你的reducer实际上需要mapper的整个输出,这超越了并行性的想法。