2010-01-23 63 views
4

我读了http://en.wikipedia.org/wiki/MapReduce的mapreduce,了解了如何在很多“文档”中获取“单词”数量的例子。但是我不明白以下行:MapReduce与函数式编程中的map-reduce组合的区别

因此,MapReduce框架将(键,值)对列表转换为值列表。这种行为与函数式编程映射和减少组合不同,后者接受任意值列表并返回一个结合了map返回的所有值的单个值。

有人可以再次阐述差异(MapReduce框架VS地图和减少组合)吗?特别是,reduce函数编程是做什么的?

非常感谢。

回答

8

主要区别在于MapReduce显然是可申请专利的。 (不禁自,,对不起......)

更为严重的一点是,我记得MapReduce论文描述了一种以大规模并行方式进行计算的方法。这种方法建立在多年前众所周知的map/reduce构造上,但超越了诸如分布数据等事项。另外,一些约束被施加在数据结构上,并由用于在map样和reduce样件的计算(约数据的键/值对的列表来的东西),所以你可能会说,MapReduce的是map & reduce组合的大规模并行性友好专业化

至于在功能上维基百科的评论被映射在函数式编程的map/reduce构建生产每一个输入值...哦,当然是这样,但这里没有限制在所有的类型的说值为。特别是,它可能是一个复杂的数据结构,或许您可能会再次应用一个变换列表。回到“计数单词”的例子,你可能有一个函数,对于文本的给定部分,产生一个数据结构映射字到出现计数,在文档上的文本(或大块文件,如情况可能会)和reduce的结果。

实际上,Phil Hagelberg在this article中就是这样。这是一个在Clojure中实现的基于MapReduce的字计数计算的有趣且极其简单的例子,其中mapreduce(apply + (merge-with ...))位 - merge-with在clojure.core的reduce中实现)。这与维基百科例子唯一的区别在于被计数的对象是URL而不是任意的单词 - 除此之外,您还有一个计数字算法,它使用mapreduce,MapReduce样式,就在那里。它可能不完全符合MapReduce实例的原因是没有复杂的工作量分布。这一切都发生在一个盒子上,尽管盒子提供了所有的CPU。

对于reduce功能的深入处理 - 也称为fold - 请参阅Graham Hutton的A tutorial on the universality and expressiveness of fold。它是基于Haskell的,但是即使你不知道语言,也应该可读,只要你愿意查找Haskell的一两件事情就行了...像++ = list连接,没有深的Haskell魔术。

+0

关于“在所述值的类型上根本没有约束”:您听起来好像MapReduce需要特定的数据结构一样。它不是。 – 2010-01-23 04:55:05

+1

那么,MapReduce文件确实将Map步骤描述为产生键/值对的列表。这不需要特定的数据结构 - 像链表或散列表 - 但肯定似乎需要特定的数据结构 - 即键和值之间的映射。这就是为什么我在答案中使用后面的表达式。话虽如此,我认为没有什么可以阻止类似MapReduce的操作在适当时继续处理不同结构的数据......但我不知道这是否属于专利的措辞(a * boo! *用于软件专利!)。 – 2010-01-23 05:13:23

+0

此外,当然没有理由为什么键/值对中的值需要具有任何特定的类型......我当然从来不打算暗示这一点。 – 2010-01-23 05:16:33

1

使用字数例如,原始官能map()会采取一组文档,任选分发集的子集,以及用于每个文档发射表示的字的数量(或一个特定字的出现)的单个值在文件中。功能reduce()然后将所有文档的全局计数相加,其中一个用于每个文档。所以你得到一个总数(无论是所有的单词还是一个特定的单词)。

在MapReduce的,在地图将发射(字,计数)对为每个字每个文档。然后,MapReduce reduce()将把的每个词的计数加起来,并将每个文档的加起来,而不将它们混合成单个堆。所以你会得到与他们的计数配对的单词列表。

1

MapReduce是一个基于将计算划分为可并行映射器和简化器的框架。它建立在熟悉的map和reduce的习惯上 - 如果你可以将你的任务结构化,以便它们可以由独立的映射器和reducer执行,那么你可以用一种利用MapReduce框架的方式编写它。

想象一下,Python解释器可以识别可以独立计算的任务,并将它们映射到映射器或简化器节点。如果你写

reduce(lambda x, y: x+y, map(int, ['1', '2', '3'])) 

sum([int(x) for x in ['1', '2', '3']]) 

您将使用功能图,并减少在MapReduce框架的方法。使用当前的MapReduce框架,涉及的管道更多,但它的概念是相同的。