• MapReduce论文笔记


    用户编写Map和Reduce函数,Map函数的调用是针对一对<k,v>的,即如果输入有5对<k,v>,那么Map函数就会调用5次。
    对于每一次:
         输入一对<k,v>,然后进行某些用户定义的操作,可以emit 出 一对或者多对的<k,v>

    这些Map函数输出的<k,v>写到本地的内存中,周期性的,这些内存中的数据对被写到本地磁盘上。

    Reduce函数的输入是< k,list<v> > ,即相同的key的value会被串在一个list里面。然后Reduce函数对于每条这样的输入进行某些用户自定义的
    操作,典型情况下,对于一次Reduce函数的调用,它会产生0个或者1个的<k,v>对。


    Reduce worker 的调用是在很多机器上并行的,Reduce的worker的数目R是由partitioning 函数(比如 hash(key) mod R)决定的,用户指定partition函数和R。
    执行流程:

    当用户程序调用MapReduce函数后,会执行以下的流程:

    1 用户程序的MapReduce库将输入文件切分成M个Split(一个Split的大小通常在16M和64M之间,GFS的block大小一般是64M),这个参数可以由用户设置,然后,用户程序会fork出许多的副本在集群的很多的机器上。

    2 在这些进程副本中,其中有一个副本进程比较特殊,叫做master进程。其他的都叫做worker进程,由master来分配任务。现在一共有M个Map任务和R个Reduce任务,master进程会选择空闲的worker进程,对它分配一个Map任务或者一个Reduce任务。

    3 被分配到Map任务的worker进程会读取自己相应部分的Split,然后worker对Split中的每对<key,value>调用一次Map函数,也就是说,如果有10对
    ,Map函数就调用10次,Map函数产生的输出buffer到本地内存中。

    4 周期性的,buffer到内存中的key/Value对会被写到本地磁盘,被partition函数切分成R份,每份一个文件。worker进程会将这R个文件的位置
    报告给master进程,master进程负责将这R个文件的位置报告给其它的Reduce worker。

    5  当一个reduce worker被master通知了这些文件的位置后,它就是用RPC去读取Map Workers上面的相应的文件。当一个reduce worker将所有它需要读取的文件都读取过来后,reduce worker进程会对所有的key/Value对进行排序(这个过程有必要,因为不同的key的pair会被map到同一个reduce worker),以便将同一个key的value给放在一个list中。这个过程中,如果数据量太大,可以使用外排。

    6 reduce worker遍历所有的Key/Value对,将unique的Key和其对应的所有的value,以<Key, list<value>>的形式传给Reduce函数,也就是说,如果有10个不同的Key,那么Reduce会被调用10次。每次Reduce函数调用的输出都会被append到这个reduce worker的一个最终的输出文件。(也就是说,一个reduce worker只会产生一个文件)

    7 当所有的Map任务和Reduce任务都完成时,Master进程唤醒用户程序,这时,用户程序的MapReduce函数调用返回给用户代码。

    最后,一共产生了R个输出文件,每个Reduce worker一个文件。这些文件会被保存到分布式文件系统上。


    Master维护的数据结构:

    Master进程需要维护每个Map,Reduce 任务的状态,有三种状态,idle,in-progress, completed,对于非idle状态的Map或者Reduce任务,它还需要维护执行这个任务的worker 机器的id。

    Master进程还需要保存每个Map任务产生的R个文件的位置信息和大小。这些信息被增量的push到in-progress状态的Reduce worker上去 

    容错

    worker failure:

    master进程会周期性的ping worker进程,如果某个worker进程在某一段时间内没有回应,那么master认为这个worker进程死了,就会把所有由死了的worker执行完成的Map任务或者in-progress状态的Map或者Reduce任务都重新标记为 idle状态,这样,这样idle的任务以后还需要被调度。

    当一个Map任务首先被worker A执行,A失败后,然后在worker B上重新执行的情况下,这个重新执行会被通知给Reduce worker。

    master failure:

    当前的实现是如果master失败,那么MapReduce任务失败,客户端可以察觉这个情况进行重试。可以定时的对master维护的数据结构进行checkpoint,这样下次一个新的master启动的时候,去读checkpoint恢复状态。

    Locality:

    输入数据是存储到GFS上面的,GFS将每个文件划分成64M的block,每个block保存3份副本,框架会将Map任务调度到有自己的输入数据的副本的机器上。

    任务粒度:

    通常M和R的大小会远远比worker machine的数量多。所以通常一个worker会做许多任务。

    关于M的选择:通常会使得每个Map任务处理的数据的大小在16M~64M大小之间(通常小于GFS的Block的大小),这样有利于locality的优化。
    关于R的选择:通常选择R为worker machine的小的倍数。

    Combiner 函数

    Combiner针对Map的输出,对Map的输出进行合并后,然后再传出去。
    比如某个Map任务会输出很多的key,Value对,如果直接把它们发出去,可能会占用大量的带宽,所以可以用Combiner函数先对这些pairs进行
    预处理,然后再shuffle。Combiner函数在执行Map任务的机器上运行。典型情况下,Combiner函数和Reduce函数差不多。

    输入

    MapReduce框架支持很多的输入模式,比如text mode,将文件的每行解析为一个key/value对,key为这行的起始字符在文件中的便宜,value就是这行的内容。还支持按key排序的key/value对的顺序存储。每种输入类型的实现都知道怎么对输入文件进行split,以使得不会破坏数据,比如text mode中,split的过程会保证split的边界在行的边界上。用户可以自定义新的输入类型。
  • 相关阅读:
    每周进度条07
    软件需求模式阅读笔记06
    每周进度条06
    软件需求模式阅读笔记05
    Django之ModelForm组件
    Django的性能优化
    分页,缓存,序列化,信号
    Django补充——中间件、请求的生命周期等
    Git基础介绍和使用
    Django基础之三
  • 原文地址:https://www.cnblogs.com/foxmailed/p/2301347.html
Copyright © 2020-2023  润新知