云计算入门(3)Google论文MapReduce阅读笔记

名词解释
MapReduce:这里指的是google的,hadoop的是根据本论文的开源实现
Iterator :遍历器
Grep: 模式匹配,简单的说就是从一大堆数据中找到特定的数据及其位置
NUMA架构 :
一种处理系统架构提供分离的存储器来给各个处理器,避免多个处理器等待一个存储器的问题,但是面对多个任务使用同一数据的情况,采用额外软件和硬件移动数据的方法,降低效能。
paxos算法:一种基于消息传递的同步算法
齐夫分布:齐夫定律,经验性定律,一个单词的出现频率与它在频率表中的排名成反比,比如第二名是第一名的1/2,第三名是第二名
crash:宕机或机器停止工作
gdb:linux下的调试工具
RPC:一种协议,用于远程调用计算机上的程序

1.概述

1.1MapReduce是什么?

mapReduce是一个抽象模型,它封装了处理和生成超大数据集所面临的并行计算,容错(通过重新执行),数据分布,负载均衡等功能的实现,用户只需要实现简单的map和reduce函数,完成分区数,分区函数,输入输出数据处理就可以利用数千台机器组成的分布式系统上的庞大计算资源,并且不需要并行计算开发经验。

1.2MapReduce有那些功能?

分割输入数据,大量计算机组成的集群上的调度,集群中计算机的错误处理,管理集群中计算机之间必要的通信。

1.3MapReduce有什么用?

解决一些需要庞大数据样本或需要处理大量数据的问题,如:
大规模机器学习问题
从互联网大量网页中提取有效信息问题。

2.编程模型

2.1简介

通过一个键值对集合产生另一个键值对集合。中间用户可以通过自定义的map函数和reduce函数对键值对集合进行处理,使得结果为包含期望数据的键值对集合。
map函数:处理输入键值对集合,输出中间键值对集合
Reduce函数:处理中间键值对集合,输出结果键值对

2.2示例

以下为计算一个大文档集合中每个单词出现次数的mapredcuce模型中用户自定义的map和reduce函数:

#include “mapreduce/mapreduce.h”
// User’s map functionclass 
WordCounter : public Mapper { 
public:  
	//map函数
	virtual void Map(const MapInput& input) {  
	 const string& text = input.value();   
	 const int n = text.size();   
	 for (int i = 0; i < n; ) {   
	 	 //  
	 	 while ((i < n) && isspace(text[i]))    
	 	  i++;   
	 	  // Find word end  
	 	   int start = i;   
	 	   while ((i < n) && !isspace(text[i]))   
	 	    i++;   
	 	    if (start < i)    
	 	    Emit(text.substr(start,i-start),”1″);  
	 	    }
	 }
};

	
	 class Adder : public Reducer { 
	 	    virtual void Reduce(ReduceInput* input) { 
	 	     // Iterate over all entries with the 
	 	      // same key and add the values  
	 	      int64 value = 0;  
	 	      while (!input->done()) {  
	 	       value += StringToInt(input->value());   
	 	       input->NextValue();  }  
	 	       // Emit sum for input->key() 
	 	        Emit(IntToString(value)); 
	 	        }
};

可以看出map函数统计每一个单词,并输出(单词,1)的键值对,而reduce则将他们聚合起来,即相同key值value相加,最后得到(单词,出现次数)的结果键值对。

2.3类型

2.3.1 输入输出的处理:

(1)怎样处理?
根据预定义数据类型(MapReduce预先实现了实现Reader接口的支持该数据类型的子类的数据类型)和Reader接口将实际的数据转换为符合map输入的key value pair形式。
(2)Reader接口是做什么的?
如果用户想要处理的数据不是预定义类型,用户通过实现接口增加MapReduce能够支持的数据类型。
(3)输出数据怎么办?
类似输入,如果不是预定义,实现对应接口。

2.3.2 执行过程中

map(k1,v1) ->list(k2,v2)  
reduce(k2,list(v2)) ->list(v2)

以上为实际代表类型(即map处理之后的所有键和值都分别相同,处理前位另一种键和值),在传递过程中通常转化为字符串类型。

2.4更多例子

2.4.1 分布式Grep

见5.1

2.4.2 URI访问频率

简单计数,类似于单词统计

2.4.3 倒转网络链接图

map函数检查每一个页面,对每一个链接输出(链接,链接所在的页面),reduce将相同链接(键)的值链接成一个list,输出(链接,链接所在的所有页面位置组成的表)。

2.4.4 每个主机的检索词向量(含有大数据过滤)

map函数为每一个页面输出(主机名(url表示),检索词向量(就是出现次数最多的单词组成的表)),redcue函数将键值对合并相同键的值,丢掉低频的检索词。

2.4.5 倒排索引

处理大量文档,map函数输出(词,文档号),reduce函数对相同词的文档号进行排序,输出排序后的列表。

2.4.6 分布式排序

见5.2

从以上案例可以看出map函数主要用于对原始文件进行处理,按键值对输出任务需要处理的信息,reduce函数则对这些信息(1)相同键的键值对合并.(2)在合并过程中,将原来的值进行数学操作获取最终值作为合并后的值或创建一个List来存放这些值,进一步的,可以对这个List进行排序等操作。

3.实现

3.1执行环境

google的mapreduce有多种实现支持多种架构:

(1)小型共享内存机器
(2)大型NUMA架构多处理主机
(3)大型网络连接集群

本文讲解的环境为:

1.linux系统的普通机器
2.带宽较低
3.故障是常态,需要故障处理
4.可靠的分布式文件系统(这里指GFS)
5.分布式调度系统(这里指chubby)

3.2执行概括

通过将Map调用的输入数据自动分割为M个数据片段的集合,Map调用被分布到多台机器上执行。输入的数据片段能够在不同的机器上并行处理。使用分区函数将Map调用产生的中间key值分成R个不同分区,Reduce调用也被分布到多台机器上执行。分区数量(R)和分区函数由用户来指定。
在这里插入图片描述

3.2.1 fork

用户程序将输入数据分片,在机器集群中自我复制。

3.2.2 assign

在所有程序中选出一个程序作为master,其它程序作为worker接受master分配的map和reduce任务。

3.2.3 read

worker根据任务提供的位置信息去读取分片数据,将其解析为键值对的形式后将其传递给map函数,map函数对其进行处理后输出中间键值对到缓存中。

3.2.4 local write

将缓存中的数据按分区函数(默认哈希函数)分成R个分区周期性的输出到磁盘,并将位置传递给master。

3.2.5 remote read

worker从master出获取到位置信息,读取后将数据排序(相同key值的value合并为一个集合)后。

3.2.6 write

一个key值一个reduce函数处理,将reduce函数处理结果按之前的分区输出到磁盘。

3.2.7 返回

以上所有任务完成后mapRedcue返回用户程序,结果保存在不同机器的R个文件中(一个redcue任务处理一个分区输出一个文件)。

注意:通常mapReduce结果用作另一个mapReduce或分布式任务输入,不需要合并到一台主机上。

3.3 master

3.3.1 master保存有哪些信息?

1.每一个map任务和reduce任务的执行状态。
2.每一个worker的执行状态。
3.M个输入数据片段各自的存储位置。
4.R个分区的中间数据的存储位置。
5.R个输出文件的存储位置。

3.3.2 master做什么?

1.分配任务给空闲worker,并传递需要数据位置信息。
2.接收每一个输出文件的位置信息。
3.将map任务执行状态传递给reduce。

3.4 机器故障处理

3.4.1 worker

(1)错误怎么发现?Master周期性的ping
(2)发现后怎么处理?重新执行该worker执行完成的map任务和正在执行的map和reduce任务
(3)为什么要这么处理?因为map任务输出的中间文件是存储在该机器上的,worker故障说明该机器无法访问,所以需要重新执行map任务。正在执行的所有任务显然都要回滚。
(4)Master还要做什么?将map任务修正信息通知所有Reduce,避免reduce

3.4.2 master

(1)丢失的数据怎么找回?Master周期性的将数据结构存入磁盘(应该是公有,至少是非本机),失效则从上一个检查点开始。
(2)发现后怎么处理?理想的是启动另一个master,但恢复很麻烦,实际上是终止mapReduce,让客户重启模型。

3.4.3 失效处理

当用户提供的Map和Reduce操作是输入确定性函数(即相同的输入产生相同的输出)时,我们的分布式实现在任何情况下的输出都和所有程序没有出现任何错误、顺序的执行产生的输出是一样的。
(1)重点是什么?原子性
(2)什么时候原子性?1.Map和Reduce任务提交2.reduce worker以原子的方式将临时文件重命名输出文件3.底层文件系统提供提供重命名的原子性。

3.5 存储位置

(1)为什么要考虑存储位置?因为网络带宽资源有限
(2)存放在那里?存放随机,但分配任务时优先分配给存放有相关输入数据拷贝的机器,不行的话就放在有输入数据拷贝的机器附近的机器,这样最大化减少执行任务时从其他机器读取数据。

3.6 任务粒度

(1)任务粒度是什么?一次map任务或Reduce任务需要处理的数据量
(2)怎样控制任务粒度?一般通过控制reduce任务的输入和输出数据分区数R决定,建议同样控制map任务输入划分的数据片段M,使得每个数据片段大小控制在16M到64M之间(方便存储位置处理);理想情况下M应比R大的多,R为worker机器的倍数。

3.7 备用任务

(1)为什么要用备用任务?为了避免落伍者拖慢MapReduce效率。
(2)什么是落伍者?因为机器硬件老化,其它任务占用资源等因素导致部分机器执行任务过慢。
(3)怎样使用?当任务快要结束时,系统调用备用任务进程来执行剩下的任务。
(4)特点?一个排序任务,多使用几个百分点的资源,节省30%的时间。

4. 扩展功能

4.1分区函数

默认分区函数是哈希函数(即关键字与哈希地址建立函数映射),根据实际需求,用户提供专门的分区函数。

4.2顺序处理

在特定分区中,reduce任务会按照中间处理结果key/value pair的关键字的增量顺序处理任务。(3.2.5)

4.3 combinar函数

(1)为什么使用Combinar函数?
1.为了提高效率(准确的说是减轻reduce函数执行前的排序合并操作的负担)
2.某些任务如计数任务的map结果存在大量重复。
(2)什么是Combinar?即在输出中间处理结果前,对map函数的处理结果在本机上进行一次类似于reduce函数的处理合并结果。
(3)他和reduce的区别在哪里?Reduce的结果写入结果文件,combinar的结果写入中间文件并把中间文件的地址通过master传送给reduce任务

4.4 限制

有些情况下,执行Map和Reduce任务过程中产生辅助的输出文件比较方便,但由于MapReduce不保证输出多个文件操作的原子性,所以当这么做时,应保证这个操作的每一个任务都是原子的。

4.5 本地执行

(1)原因:在分布式系统中调试map和reduce函数的bug十分困难
(2)解决方案:MapReduce提供了本地版本,使得MapReduce可以在本地计算机上执行,从而可以方便的使用本地调试和测试工具。

4.6 损坏跳过机制

(1)原因:用户程序的bug可能产生让任务机器宕机等问题,通常解决方案是修复bug重新运行但是有些bug很难修复(比如没有没有源代码的第三方程序),因此MapReduce提供了一种执行模式,使得执行时可以跳过这些有问题的记录。
(2)实现方式:每一个worker程序产生一个信号处理函数捕获内存段异常和总线错误(通常引起宕机的两种错误),程序失败时,函数向master发送消息,说明最后执行的记录序号,当多次处理该记录失败时,master标记该记录,告诉worker跳过该记录。

4.7状态信息

Master通过http服务器显示一组状态页面,用户通过访问这些页面可以的得到MapReduce执行的相关信息,特别的,最顶级页面有worker失效时正在执行的Map和Reduce任务信息,方便缩小调试范围。

4.8计数器

(1)简介:MapReduce通过计数器来检查进度和任务执行完整性,它有自带的计数器,比如已经处理的键值对数量输出的键值对数量,但更多的需要用户自己定义。
(2)实现:用户在程序中创建一个计数器对象,然后在map和reduce函数中对它进行操作。

5.实例

在1800台机器(机器详细信息略)的集群中对1TB数据执行以下任务。(有意思的是,这两个实例的Reduce都是恒等函数)。

5.1 分布式模式匹配

(1)查找3个字符的大小的字符串在1TB数据的位置。
(2)输入数据拆分为64M的块(M=15000)。
(3)因为出现频率较小,最后输出一个文件(R=1)。
在这里插入图片描述
(4)任务一共进行了150秒,上图是任务准备完成后开始处理的处理速度随时间变化图。
(5)启动阶段花了一分钟左右,时间主要花在3个方面:
** 程序自我复制花费的时间(即3.2.1)**
文件系统打开输入文件
master通过输入文件位置信息和worker所在机器进行本地优化(即3.5),得出解决方案花费的时间
(6)如图,执行阶段大概分为四部分:
1.前30秒缓慢上升,master逐渐分配map任务,执行机器逐渐增多
2.30-50秒快速增长,部分map任务执行完成,开始有worker执行reduce任务
3.50-70秒快速下降,50秒时达到集群上限,几乎所有的机器都在执行任务人,然后所有map和reduce任务都以分配,完成任务的机器处于空闲状态。
4.落伍者出现,备用任务处理,但是备用任务处理依然花时间,所以拖慢了结束速度。

5.2 分布式排序

(1)Map函数从文本行中解析出10个字节作为排序的key,把key和原文本行作为键值对输出。reduce函数恒等(因为redcue任务已经做了排序)。
(2)输入数据分为64M的块(M=15000),输出结果作个备份(输出2TB数据)存储到4000个文件中(R=4000)。
(3)分区函数需要保证分区间相对有序(即一个分区内是无序的,但这个分区内的所有数据都比另一个分区的数据大或小),作法是先用另一个处理数据较小的mapReduce进行采样,得到分区的分界线估值,然后根据分界线依次把数据放入相应分区。
在这里插入图片描述
(4)左上图:map任务读取数据速度,比5.1慢是因为map处理和输出信息中间文件(5.1输出几乎没花时间)
(5)左中图:reduce任务从map获取中间文件信息速度,第一波开始:第一个map任务执行完成,第一个高峰:几乎所有机器都有在执行Reduce,而一台机器只能执行一个Reduce任务。第二波,开始有Reduce任务完成。
(6)左下:Reduce结果输出到磁盘速度,第一个Reduce任务完成和输出开始有延时:排序占用资源。
(7)读取速度比排序速度和输出速度快:本地优化策略的成果。
输出结果速度过慢:输出数据写了两份来保证可靠性,当然可以通过容错编码的方式解决可靠性问题来做优化。
(8)b图为关闭备用任务的结果。(备用任务牛!!!!)。
(9)c图有意kill了200台机器的执行结果。(MapReduce的故障处理系统牛!!!!)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值