songjingsong

这是我看的第一篇论文,我真的是硬着头皮去看,出乎意料,虽然磕磕绊绊,但是竟然一气呵成,我读完我发现为什么其思想竟然如此的简单。
Mapreduce,有人翻译成map-->映射,reduce-->归总,map的目的是分而治之,reduce是合。

1. mapreduce的提出背景

在google需要对海量的原始数据进行处理,但是由于输入的数据太多,导致无法在可接受的时间内完成,所以需要一个新的抽象模型,利用大量的普通的计算机来对这些数据进行并行化计算,降低处理时间。

2. 如何进行计算(计算模型)

简单来说,就是讲大的数据集合分块,在大量的计算机上执行,产生的中间结果,再由另外一批程序汇总合并。其原理是:利用一个输入key/value pair集合来产生一个输出的key/value pair集合。

map (k1,v1)             →    list(k2,v2)
reduce (k2,list(v2))    →    list(v2)

即用户的计算,可以用简单的函数来表达:Map和reduce,通过将Map调用的输入数据自动分割为M个数据片段的集合,Map调用被分布到多台机器上执行。

3. Mapreduce如何处理分布式的

仔细观察mapreduce的执行流程,会发现,所有的任务都是由master去分配的,交由不同的worker去执行,首先把原始的输入文件切分成多份,交与worker执行map,生成中间文件(intermediate file)后,再指定执行reduce任务的worker,最后生成结果文件。
这是一个很浅显易懂的分布式的计算过程,但是我们我们如何指定worker执行的呢?如果worker执行失败,我们怎么处理? 如果master故障,我们怎么处理?

4. 负载均衡的实现

所谓的负载均衡就是,保证不同的worker机器上的任务数量分布均匀,在并行计算的时候,我们总是希望分配的每一个task是以相同的粒度大小并且最后的执行时间相差不大,但是在集群中,如果切分的数据不一致或者在执行过程中某个机器出现故障,就会拖慢整个任务的完成时间(这个类似于操作系统中的流水线模式,大家了解一下)。

4.1 任务粒度

任务粒度实际上是指,我们在不同的阶段把执行的数据分片,交与不同的worker执行。我们把map阶段分成M个片,reduce阶段分成R个片。通常来说M和R应该比worker的机器数量要大得多,这个是为了保证每个worker可以执行不同的工作来提高负载均衡的效率。
在我们的实现里,M和R的范围是有大小限制的,因为master必须做O(M+R)次调度,并且保存O(M*R)个状态在内存中.此外,R经常被用户限制,因为每一个reduce任务最终都是一个独立的输出文件.实际上,我们倾向于选择M,以便每一个单独的任务大概都是16到64MB的输入数据。

4.2 分割函数(如何切分?)

MapReduce用户通过master指定reduce任务和reduce任务需要的输出文件的数量.在中间key上使用分割函数,使数据分割后通过这些任务。通常默认我们采用hash函数,这个函数,一般可以导致平衡的分割,也有一些其他的场景下不同的函数。
上面的这个翻译说实话有些难懂,我通常这么理解,在map阶段中生成key/value的中间文件,通过在key的分割操作来分割文件,形成一个个任务,指定reduce来执行。一般来说,其函数类似于(例如,hash(key) mod R),比如我有个2个输入文件,有3(R)个reduce worker,通过对key的分割,会生成三个文件,分别类似于XXX-01-00 XXX-01-01 XXX-01-02 XXX-02-00 XXX-02-01 XXX-02-02, 生成了6个中间文件,最后通过reduce的执行,汇总成了3个 结果文件。

4.3 落后任务

一个落后者是延长MapReduce操作时间的原因之一:一个机器花费一个异乎寻常地的长时间来完成最后的一些map或reduce任务中的一个。
当一个MapReduce操作将要完成的时候,master调度备用进程来执行那些剩下的还在执行的任务.无论是原来的还是备用的执行完成了,工作都被标记成完成.我们已经调整了这个机制,通常只会占用多几个百分点的机器资源.我们发现这可以显著的减少完成大规模MapReduce操作的时间.

5. 故障处理

mapreduce从设计上来说就是为了并行计算,但是在集群中,如果master节点失效,我们要怎么处理?如果某一个worker执行失败,在不同的执行阶段分别要怎么处理?

5.1 master故障

在mapreduce的设计中,master有一个数据结构,这个数据结构值保存每一个map和reduce的任务的执行状态(空闲,工作,完成等)。它用来管理任务的执行状态。master会定期的通过心跳(ping)来判断每个worker的状态。master会定期的把上述的数据结构checkpoints写入到磁盘中,如果master故障,可以从最后一个checkpoint中启动一个新的master进程。

5.2 worker故障

master周期性的ping每个worker.如果master在一个确定的时间段内没有收到worker返回的信息,那么它将把这个worker标记成失效.因为每一个由这个失效的worker完成的map任务被重新设置成它初始的空闲状态,所以它可以被安排给其他的worker.同样的,每一个在失败的worker上正在运行的map或reduce任务,也被重新设置成空闲状态,并且将被重新调度.

但是worker故障有很多原因,比如因为网络故障导致master没有ping到worker A(但是A是正常运行的),同时会启动另一个worker B, A和B同时执行。在不同的阶段有不同的处理方式:
在map阶段,由于其输出的结果是存储在自己的磁盘上的,所以本身是不可访问的,同时当master把任务分配给B的时候,也会告知其余执行reduce的worker,从B上去拉取中间文件。
在reduce阶段,由于其生成的结果文件是保存在文件系统中的,会保证最终生成的文件具有唯一性,不会造成重复,同样不会造成影响。

上面就是在读mapreduce论文中我所思考的会出现的问题,但是实际上在真正的实现过程中肯定会出现更多的问题~

相关文章: