简介
在过去的五年,作者和许多其它在谷歌的人实现了上百个专用的计算来处理大量的原始数据,例如爬取的文档、web请求日志等等。这些计算产生各种各样的派生数据,例如倒排索引、web文档的图结构的各种表示、每个网页有多少页、一天内最频繁被查询的集合等等。大部分这样的计算在概念上都是很简单的。但是它们的输入通常都很大,计算必须被分配到成百上千台机器上才能在一个合理的时间内完成。问题在于,如何并行计算,如何分布数据并且处理失败。这些问题让原本简单的计算变得很复杂,需要大量复杂的代码来解决这些问题。
为了应对这种复杂性,我们设计了一种新的抽象,它允许我们简单第表示计算而不用考虑细节,将并行化、错误容忍、数据分布以及负载均衡等混乱的细节封装在库中。我们的抽象受到了Lisp以及许多其它的函数式编程语言中存在的map和reduce原语的启发。我们发现,我们的大部分计算都涉及对输入中的每个逻辑“record”应用一个map操作,以计算生成一组中间的键值对,然后对于具有相同键的键值对应用一个reduce操作来将派生数据合适地组合到一起。我们使用一种用户指定map和reduce操作的函数模型,这允许我们很简单地并行化大量的计算并且使用重新执行作为错误容忍的主要机制。
这项工作的主要贡献是提供了一个简单和强大的接口,可以实现大规模的自动化并行和分布式处理,以及实现了这个接口,可以在由普通机器组成的大型集群上达到高性能。
第二节描述了基本的编程模型并且提供了几个例子。第三节描述了基于我们基于集群的计算环境的MapReduce接口的实现。第四节介绍了一些我们发现有用的对于编程模型的改进。第五节是对于我们的实现在执行一些不同的任务时的性能度量。第六节探索了一些MapReduce的应用,不仅仅是谷歌,也包括我们使用它作为重写我们生产系统索引的基础。第七节讨论了相关和未来的工作
Programming Model
计算任务采用了一组包含键值对的输入,并且产生一系列键值对作为输出。MapReduce的使用者用两个函数表示计算:Map和Reduce
Map读取一个键值对作为输入,然后产生一组中间键值对。MapReduce库将所有中间键值对按照相同的键I分组并将它们传递给Reduce函数
Reduce函数接受一个键I和在所有中间键值对中这个键所对应的值的集合。它将这些值合并起来形成一个可能更小的值的集合。例如每次对于Reduce的调用只输出1和0作为值。中间值经过一个迭代器提供给用户reduce函数。这允许我们处理那些因为数量太多而不能存放在内存中的值。