0%

Mapreduce论文总结

Mapreduce

论文地址: MapReduce: Simplified Data Processing on Large Clusters

Mapreduce分布式编程模型,理解起来比较简单,主要总结一下模型+实现细节

编程模型

将任务划分为Map和Reduce两个阶段由用户实现,每个阶段输入输出key-value对(形象理解可以看论文中的例子)

  1. Map 输入key-value,经过处理输出新的中间 key-value对,由MapReduce执行程序,将相同中间key聚集发送给某一个reduce执行程序
  2. Reduce 输入一个中间key和key对应的value列表,reduce执行具体聚集操作后,获得最终的输出key-value

实现

基本执行流程包括

  1. 将输入文件划分为m份(16-64mb),对应m个map任务。在集群上启动多份应用程序
  2. 其中一个master程序,将map任务和reduce任务分配给空闲的worker(不同的worker可能是一台机器)
  3. map任务程序首先执行,读取对应的文件块,将输出中间键值对缓存在内存中
  4. 每隔一段时间,map worker将缓存中的中间键值对存储到本地磁盘(根据key->reduce的映射进行partition)。这些中间键值对的地址,将传给master worker,供reduce worker远程读取
  5. reduce worker由master唤醒后,通过RPC读取映射到本reduce worker的中间键值对输出
  6. 当属于某个reduce worker的中间键值对读取完成后,按照中间键值排序,对不同的key分组处理,也就是所谓的reduce输入key-value list
  7. 所有reduce程序完成后,结束mapreduce过程

总结一下,就是map->partition->sort->reduce

容错

为map和reduce任务定义了执行状态存储在master结点中,通过状态实现容错,每个任务的状态为

  1. idle 等待处理
  2. in-progress 处理中
  3. completed 处理完成

master定期ping所有执行或者执行过任务的worker,若worker失效,将worker上执行过的所有任务(in-progress或者completed)状态设置为idle,等待分配给其他worker处理。

  • 若mapreduce任务执行在类似GFS的文件系统上,则complete类型任务不需要重新执行,因为输出文件不仅仅存储在失效的worker上
  • 每当一个map任务重新执行后,需要通知所有的reduce任务该map任务的新执行

性能

  1. map任务分配任务时遵循“靠近输入文件的原则”,首先考虑分配在包含输入文件的机器上,其次考虑靠近存储文件的机器上(移动计算比移动数据更有效)
  2. 用一些backup worker,替代拖后腿的worker,提升系统效率下限
  3. map和reduce任务数量M和R要比机器数量大得多,以更好地负载均衡(每个workerp平均一个任务都分不到,谈何负载均衡?)和恢复错误(没太理解?)

问题思考

  1. 如何把map任务的输出分配给R个reduce worker(partition

    • 原则:相同key必须分配到同一个reduce worker

    • 最简单方式就是使用key的哈希值进行映射

  2. 既然有了partition,为什么要combiner?

    • 相同key值的key-value对可能很多(例如wordcount),通过网络传播对带宽压力较大,
    • 在map端先进行一部分的reduce操作,合并重复key,也能一定程度减轻reduce的计算压力
  3. 直觉上为什么mapreduce能解决分布式计算问题?

    从程序角度看,不管的单机还是分布式,其本质都是程序读取输入->程序计算->程序输出结果,我要实现分布式程序,无非要实现 分布计算 = 单机计算

    1. 程序输入: 分布式文件存储在不同机器上,自然而然能够想到多个map程序读取文件的操作
    2. 程序计算:难点在于分布式读入文件,我如何实现等价于单机计算的效果?我觉得这就reduce设计巧妙地地方,文件的分块不等于计算的逻辑分块,通过map—>reduce程序的计算,实际上将文件的分块映射到计算的逻辑分块
    3. 程序输出: reduce输出实际逻辑子问题的输出->实际问题的输出(这一点我还没想明白,类似于归并排序 reudce制作到了归没有做并)

    以wordcount为例,讲一下我的理解

    1. 文件分块:整个文本文件->子文本文件块 (问题数据规模上分布
    2. 计算逻辑分块:统计每个不同字的字数->单独统计每个字的字数(问题逻辑规模上分布

    map解决每个文本文件内字数的统计,reduce解决每个字字数统计

总结

mapreduce只看理论理解还是太表面,还是需要写代码实战,学到了继续深化吧