论文阅读笔记--MapReduce

来源:互联网 发布:网络统考app 编辑:程序博客网 时间:2024/06/06 20:58

原文:MapReduce: Simplified Data Processing on Large Clusters

1 编程模型

  计算任务的输入时key/value对,产生结果也是key/value对。MapReduce库的用户可以将计算任务分为两个部分:Map 和 Reduce
  Map, 用户所写,将键值对作为输入并且产生中间结果key/value。Mapreduce库会根据中间结果的Key将所有中间结果归类,然后将这些中间结果传输给Reduce。
  Reduce,用户所写。接收key 为I的中间结果key/value。然后合并这些value。中间结果是迭代的提供给用户的reduce函数的,这就可以让我们处理更多的数据,以免内存爆炸。

1.1 例子

  例如我们想统计一个大文本每一个单词的数量。mapreduce的伪代码如下:

  map(String key, String value):    // key: document name    // value: document contents    for each word w in value:      EmitIntermediate(w, "1");  reduce(String key, Iterator values):    // key: a word    // values: a list of counts    int result = 0;    for each v in values:      result += ParseInt(v);    Emit(AsString(result));

  Map函数遍历字符串中的word,产生word/”1”这样的key/value。reduce函数将这些中间结果加起来。论文里还有其他例子,这里不细说了。

2 实现

  mapreduce的实现由很多种,要看环境。不同的硬件环境适合不同的实现。本文的实现针对google的分布式计算。具体可以看论文,大概就是上千台的普通机器,2-4G的内存,linux操作系统。

2.1 Execution Overview

  Map是在不同的机器上执行的,并且输入会被自动的分工成M数据子块到不同的机器上。每一个数据块可以被在不同机器上并行处理。Reduce则把中间结果合成R各peices(用户用一个hash(key) mod R)。R的值以及partition函数。下图为mapreduce实现的数据流。(图中序号和一下过程对应),当用户调用Mapreduce时,以下操作序列将会被触发
这里写图片描述
1. MapReduce 首先将input files分成M各部分。 每一个部分大小可以被用户作为参数控制。然后将程序复制到集群上的很多机器上并启动。
2. 有一个程序拷贝比较特殊,master。master分配任务给其他workers。其中有M个map任务以及R个reduce任务。master找出空闲的workers并且分配给它map任务或者reduce任务。
3. 一个被分配map任务的worker,读取对应split的数据。将数据转化为key/value并且传给用户定义的Map函数。最后Map函数所产生的key/value缓存在内存中。
4. 时不时地,缓存的数据会写入到自己的磁盘中,然后通过partition函数将这些数据分割到对应的R区内(取模)。缓存的地址也会传输给master,master会将这些地址发给reduce workers.
5. 当一个reduce workers接受到这些上述地址,它会用远程程序,读取缓存数据。当reduce workd有所有的中间数据时,它会将中间key排序,目的是为了将同样的key放在一起。
6. reduce worker迭代被排序过的key,并将这个Key,以及其对应的values传给用户定义的reduce函数。reduce的输出被写入到输出文件
7. 当所有的map和reduce 任务执行完毕的嘶吼,Master会唤醒用户程序。这时,用户程序的mapreduce调用会返回。

2.2 master 数据结构


  master有好几个数据结构。对于每一个map任务和reducd任务,它持有它们的状态(空闲、执行中,或已完成),还有work机器的唯一标识。另外还有map产生的中间结果的地址以及中间结果File的大小等。

2.3


  因为MapReduce是通过大规模集群来处理大数据的,所以就要有容错机制。

2.3.1 Worker Failure


  master ping 周期性的ping每一个worker。如果在一段时间没有收到某个worker的response,则master认为这个worker已经挂了。所有在这台机器执行map任务都被重新设为idle状态,然后就可以被其他worker重新调度。
  被完成的map任务,但是执行他的机器挂了,也会在其他机器上重新执行。这时因为output被保存挂掉的机器上无法被访问。而完成的reduce任务不用重新执行,是因为output保存在全局文件系统中。(例如hdfs)
  当一个Map任务本来在worker A执行,后来又在B执行(A挂了)。那么所有的reduce worker将会被通知重新执行,所有没有从A读取数据的reduce 任务会从B读取数据。所以MapReduce是可以容忍节点宕机的。

2.3.2 Master Failure


  为Master设置副本,当主节点挂的时候,则启动一个copy,回复到最晚的那个状态。尽管如此,google的实现是停掉MapReduce计算,如果master fail的话。客户端可以检查master的状态。

2.3.3 Locality


  调度Worker的时候会尽量给持有Input数据及副本的机器分配任务,实现不行也会分配给离输入数据近的机器。

2.3.4 任务的粒度


  map操作会将输入数据拆分然后分给不同的worker执行,那么分多少合适呢。理想来说,M和R应该比机器数量大得多,这样可以负载聚恒,也可以当出现节点挂的时候更快的恢复。但是过多的map 任务会导致过多的维护信息。在实践过程中,一个Map任务大概选择16MB-64MB的数据作为输入数据。例如M=200000 R=5000,用2000台机器。

2.3.5 备用任务


  当任务被拆分,分开执行时,总会有“拖后腿的”,这就导致整体mapreduce要等那个“拖后腿的任务”。拖后腿的原因有很多,例如硬盘错误导致读取速度下降,或者是这台机器很忙仍需要执行其他任务,导致CPU竞争激烈等。我们有一个通用的机制来减少“落伍者”出现的情况。当一个MapReduce操作接近完成的时候,master调度备用(backup)任务进程来执行剩下的、处于处理中状态(in-progress)的任务。无论是最初的执行进程、还是备用(backup)任务进程完成了任务,我们都把这个任务标记成为已经完成。我们调优了这个机制,通常只会占用比正常操作多几个百分点的计算资源。这样显著减少了MapReduce执行任务的时间,关掉备用机制要多花44%的时间。

3 Refinement


  这里主要讲一些工程上的东西,可以进去直接看论文。

原创粉丝点击