【问题标题】:The difference between MapReduce and the map-reduce combination in functional programmingMapReduce与函数式编程中map-reduce组合的区别
【发布时间】:2010-01-23 03:15:38
【问题描述】:

我在http://en.wikipedia.org/wiki/MapReduce 阅读了mapreduce,了解了如何在许多“文档”中获取“单词”计数的示例。但是我不明白以下行:

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

有人可以再次详细说明区别(MapReduce框架VS map和reduce组合)吗?特别是,reduce 函数式编程有什么作用?

非常感谢。

【问题讨论】:

    标签: functional-programming mapreduce


    【解决方案1】:

    主要区别在于 MapReduce 显然是可申请专利的。 (忍不住,抱歉……)

    更严肃地说,我记得 MapReduce 论文描述了一种以大规模并行方式执行计算的方法。这种方法建立在多年前广为人知的 map/reduce 构造之上,但超越了诸如分发数据等问题。此外,对正在操作的数据结构施加了一些限制,并由map-like 和 reduce-like 计算部分(关于数据进入键/值对列表的事情),所以你可以说 MapReduce 是一个大规模并行友好的专业化强> mapreduce 组合。

    至于 Wikipedia 上关于函数式编程的 map / reduce 构造中映射的函数的评论,每个输入产生一个值...好吧,当然可以,但是这里 根本没有限制关于所述值的类型。特别是,它可能是一个复杂的数据结构,例如您将再次应用map / reduce 转换的事物列表。回到“计数单词”的例子,你很可能有一个函数,对于给定的文本部分,它会生成一个数据结构,将单词映射到出现次数,map 覆盖你的文档(或文档块,如情况可能)和reduce结果。

    事实上,这正是 Phil Hagelberg 在this article 中发生的事情。这是在 Clojure 中使用 map 和等效于 reduce 的类似 MapReduce 字数计数的计算的一个有趣且极其简短的示例((apply + (merge-with ...)) 位 - merge-with 是根据 reduce 实现的在 clojure.core 中)。此示例与 Wikipedia 示例之间的唯一区别是被计数的对象是 URL 而不是任意单词——除此之外,您还有一个使用 mapreduce 实现的计数单词算法,MapReduce 风格,对那里。它可能不完全符合 MapReduce 实例的原因是不涉及复杂的工作负载分布。这一切都发生在一个盒子上……尽管在盒子提供的所有 CPU 上。

    要深入处理 reduce 函数(也称为 fold),请参阅 Graham Hutton 的 A tutorial on the universality and expressiveness of fold。它是基于 Haskell 的,但即使您不了解该语言也应该是可读的,只要您愿意随时查找一两个 Haskell 东西......像++ = 列表连接,没有深度Haskell 魔法。

    【讨论】:

    • 关于“对所述值的类型完全没有限制”:您听起来好像 MapReduce 需要特定的数据结构。它没有。
    • 好吧,MapReduce 论文确实将 Map 步骤描述为生成键/值对列表。这不需要特定的数据结构——如链表或哈希表——但确实似乎需要特定的数据结构——即键和值之间的映射。这就是为什么我在答案中使用后一种表达方式。话虽如此,我想没有什么可以阻止类似 MapReduce 的操作在适当的时候对不同结构的数据进行处理......虽然我不知道这是否属于专利的措辞(a 嘘!软件专利!)。
    • 另外,当然没有理由说明键/值对中的值需要是任何特定类型的......我当然从来没有暗示过。
    • 实际上,MapReduce 很少用于字符串。它最初是为描述和包含任意数据结构的协议缓冲区 (code.google.com/p/protobuf) 制作的。键值对只是一个步骤,它允许单个 Map() 在一次运行中提供许多 Reduce() ,因为每个键都有一个 Reducer。
    • 嗯,这是真的,但是它并没有改变 MapReduce 在原始论文和专利权利要求中提出的事实(当然是论文,我几乎无法阅读其法律术语的权利要求,所以这只是据我所知)确实涉及键/值业务。这是因为工程上对如何分配事物的关注,这一事实强化了 MapReduce 超越 FP map+reduce 的观点。然而,从抽象的角度来看,根据键将数据划分为块只是 reduce 步骤的一部分。所以我还是会说 MapReduce 是 m+r 的一个特化。
    【解决方案2】:

    使用字数统计示例,原始函数 map() 将获取一组文档,可选择分发该集合的子集,并为每个文档发出一个表示单词数的值(或特定单词的出现)在文档中。然后,一个功能性的reduce() 会将所有文档的全局计数相加,每个文档一个。所以你会得到一个总计数(所有单词或特定单词)。

    在 MapReduce 中,地图会为每个文档中的每个单词发出一个(单词,计数)对。然后,MapReduce reduce() 会将 每个文档 中的每个单词 的计数相加,而不会将它们混合成一堆。所以你会得到一个单词列表及其计数。

    【讨论】:

      【解决方案3】:

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

      想象一个 Python 解释器,它可以识别可以独立计算的任务,并将它们分配给 mapper 或 reducer 节点。如果你写了

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

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

      您将在 MapReduce 框架中使用函数式 map 和 reduce 方法。在当前的 MapReduce 框架中,涉及的管道更多,但概念相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-12
        • 2012-07-07
        • 2018-10-24
        • 2021-06-20
        • 2019-06-12
        • 1970-01-01
        • 2011-02-02
        • 1970-01-01
        相关资源
        最近更新 更多