Google编程学院:并行编程及MapReduce简介

原文地址:http://code.google.com/intl/zh-CN/edu/parallel/mapreduce-tutorial.html

 

本文目录

1.读者和预备知识

2.串行编程与并行编程

3.基础知识

4.MapReduce

5.MapReduce执行概要

6.MapReduce例子

7.参考资料


 

 

1.读者和预备知识

本教程包含并行编程和MapReduce编程模型。预备的知识包括一定的编程经验(C++,Java etc)、数据结构和算法知识。

2.串行编程与并行编程

     在早期的计算机,程序都是串行的,那意味着,一个程序由一连串顺序执行的指令组成。它可以在一个处理器里从头到尾完成全部工作。

为了提高程序的性能和效率,并行编程应运而生。在并行式程序里,处理过程被分为多个部分,每个部分可以并发执行。其中每个部分里面的指令可以同时在不同的CPU上运行。这些CPU可以在同一台机器上,也可以在网络中的一组机器上。

     并行式程序不仅运行更快,而且能被用于解决分布式大数据集的问题。当你有一组网络中的机器、大量的CPU、一个分布式文件系统和读写海量文件的权限,这时候,并行式程序将显得非常实用。

3.基础知识

    建立并行式程序的第一步是确定能并行执行的任务,或者能并行处理的数据。不过,有时候这并不可能。考虑一个Fibonacci(斐波那契)函数:

Fk+2 = Fk + Fk+1

   计算上述函数的程序并不能被并行化。因为每次计算都基于前一次计算的值。

   而一般的情况是,我们需要处理一批大量的数据,这些数据可以被分成同等大小的若干份,例如一个大的数组被分成子数组。如果每个数组的元素都需要被处理,而且数组间没有依赖关系,执行的计算任务之间也不需要通信,这样的话将是一个执行并行式计算的理想环境。下面介绍一种一般的实现并行计算的技术----master/worker(master和worker分别代表计算环境中主/从的角色----译者注)。

 

Master:

  1. 初始化需要处理的数组,然后根据可用的worker数量,把数组分解成若干部分(子数组)
  2. 把子数组发送给worker
  3. 接收worker返回的处理结果

worker:

  1. 接收master发送过来的子数组
  2. 对子数组进行处理
  3. 向master返回结果

      一般来说,在并行式系统里,负载平衡是指在处理器之间平衡分配任务,避免出现某些处理器有等待执行的任务而某些处理器则空闲的情况。而上面提到的这个模型应用的是静态的负载平衡,它常用于每台机器负责同等工作量的情况。

     静态负载平衡在分配任务的时候并不考虑现时的网络负载情况。而动态负载算法虽然花费更高,但它更加灵活。在分配任务之前它会对网络负载进行考虑。

下面考虑一个MASTER/WORKER的具体例子:估算PI。首先,设有一个圆在正方形内。如下图.

 

 

所以,正方形的面积As = (2r)2 即4r2 

圆的面积Ac = pi*r

所以有,

pi = Ac / r2

As = 4r2

r2 = As / 4

pi = 4 * Ac / As

   通过上面代数运算的分析,我们可以试着用并行式的方法解决这个问题。

首先,问题的解决可以分解为以下四步。

1.在正方形内随机产生一些点

2.计算同时在圆内和正方形内的点

3.计算r,r = 圆内的点数目/所有正方形内的点数目 

4. PI= 4*r

然后,我们试着对这个过程进行并行化处理。

4.MapReduce

      上面,我们给出了一些并行式编程的列子,现在我们看看MapReduce的编程模型。这个模型的灵感来自于函数式编程语言Lisp中的map(映射)和reduce(化简)。

      在Lisp里面,map接收一个函数和一个序列作为输入,然后把这个输入的函数应用于这个序列里的每个元素。而reduce则通过一个二进制操作把一个序列的元素联合起来,例如它可以使用加法对序列里的元素求和。

      MapReduce是受到这些概念的启发而产生的一个模型。Google对这个模型进行了实现,用来处理巨量的数据,例如网络爬虫得到的文档和web访问到的记录。由于数据量大,它必须被分布到数千台机器进行处理。因为计算分布到不同的CPU,且每个CPU处理不同的数据集,所以这样的分布式处理意味着可以采用并行计算。通过MapReduce的抽象,google工程师可以简单地进行运算,而不必考虑并行运算的细节、数据的分配、负载平衡和错误处理。

     MapReduce 库的用户指定一个Map函数,通过这个函数接收key/value对,然后产生一系列的中间key/value对。MapReduce库把所有具有相同key的中间对组合起来,传递到reduce函数。

     Reduce函数同样由用户指定。它接收一个中间key和对应该key的一个数据集,然后把这个大的数据集组合成一个更小数据集。

下面考虑一个统计词频的问题。

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 countsint result = 0;

for each v in values:  result += ParseInt(v);

Emit(AsString(result));     [1]

在上面的例子中,map函数对每个单词记一次计数(在这个例子中为“1”)。reduce函数把同一个单词的计数全部加起来。

5.MapReduce执行概要

    对于需要处理的数据,首先M块,然后把数据块分配到多台机器上。每个机器对数据块进行Map函数处理。这样,输入的数据块就能同时在不同的机器上进行并行处理。

     接着,对map操作产生的中间key进行分块,分成r块。分块函数和分块数目可由用户指定,例如可以采用函数hash(key)modR进行分块。

下面列出了一个MapReduce操作的整体流程。

 

  1. MapReduce库把输入的文件(数据)分成M块(一般每块16-64M),然后机器集群中运行多个mapreduce程序的副本。
  2. 其中有个特别的副本:master。其余的都是worker。worker执行master分配的任务。总共有m个map任务和r个reduce任务需要分配。master选择空闲的worker分配这些任务。
  3. 被分配到map任务的worker读取对应的数据块。然后通过数据块分析出key/value对,然后把它们传递到用户定义的map函数进行处理,产生中间的key/value对,在内存进行缓存。
  4. 每隔一段时间,被缓存的数据对通过分区函数被映射到不同的R个区域,然后写入到本地磁盘。然后这些数据的位置被传递到master,master把这些位置传到负责reduce任务的worker
  5. 负责reduce任务的worker接收到这些位置信息以后,使用RPC读取这些数据。当所有中间数据读取完毕后。通过中间key对数据进行分组,key相同的数据对被分到同一组。
  6. reduce worker把整理后的数据传递到reduce函数进行处理。对于根据reduce的分区,reduce函数的输出结果被写入到不同的输出文件。
  7. 当所有map和reduce操作完成后,master唤醒用户程序。
  8. 完成后,MapReduce的执行结果被保存在R个输出文件。

     为了检测可能的故障,master周期性地ping各个worker。如果某个worker响应超时,master把worker标识为故障。这个worker处理的任何map操作结果需要回滚,回滚后的数据可由其他正常的worker进行处理。类似的,任何在故障机器上的map或reduce任务会被标识为空闲(未分配),master重新对这些任务进行分配。

     因为map任务把处理后的数据存储在本地磁盘上,所以故障机器上的map任务需要重新执行。而reduce任务吧输出数据存储到全局文件系统,所以即时发生故障也不需重新执行。

6.MapReduce例子

下面是一些mapreduce应用中有趣的例子。

  • 分布式grep(正则表达式匹配):map函数对符合样式(正则表达式规则)的行进行标识。reduce函数是一个恒等函数,它只负责把中间数据发送到输出文件。
  • URL访问计数:map函数处理web页面的请求日志。reduce函数根据URL进行累计。
  • web连接图反转:map函数输出数据对<目标URL,可能的连接>。reduce函数输出一个数据对<目标URL,所有可能的连接列表>。
  • 主机的词条矢量:词条矢量通过<词条,频率>数据对总结了文档或文档集里面重要的单词。map函数对输入文档进行<词条,频率>分析。reduce函数把所有中间结果发送到一台特定的主机。主机把根据词条进行累加,丢弃频率低的词条,最后得出一个合适的词条进行主机描述。
  • 反向索引:map函数对每个文档进行索引分析,产生一串数据对。reduce函数接收含有特定的单词数据对,然后对相应的文档ID进行排序,得出一个<索引,文档ID列表>对。所有这些输出的数据对组成了一个简单的反向索引。可以通过这种方式对单词的位置保持跟踪。

 

7.参考资料

[1] Dean, Jeff and Ghemawat, Sanjay. MapReduce: Simplified Data Processing on Large Clusters http://labs.google.com/papers/mapreduce-osdi04.pdf

[2] Lammal, Ralf. Google's MapReduce Programming Model Revisited. http://www.cs.vu.nl/~ralf/MapReduce/paper.pdf

[3] 开源MapReduce: http://lucene.apache.org/hadoop/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值