分布式学习:MapReduce
MapReduce的设计
MapReduce 是一种用于处理大规模数据集的编程模型和处理框架,它执行的三个阶段:
-
map阶段:master将输入数据分成M个独立数据块,并将每一个数据块交给一个map-worker来执行map任务(将输入数据转换为键值对的形式,然后对每个键值对执行某种操作,生成中间结果)
-
shuffle阶段:map-worker将中间结果用分区函数分成R个区域,按照键排序,以便将同一个键的数据传递给同一个reduce任务,然后map-worker将这些区域的位置都传给master
数据一开始经过map-worker处理后按行存储,也就是在每个map-worker上都存储了一行kv对,但最后的reduce-worker需要按列处理这些kv对,每个reduce-worker也就需要遍历所有的map-worker取出特定的kv对,这个过程叫做洗牌(shuffle)
-
reduce阶段:master收到map-worker传回的各个分区的位置后,转发给reduce-worker,执行reduce任务(将相同键的数据聚合在一起,并执行用户定义的操作,生成最终的输出结果),并写入到共享文件服务中(比如GFS)
MapReduce提供的容错
woker发生故障:
-
检测:master定期ping各个worker,没收到回复则标记worker为失败
-
处理:将失败map-worker完成或正在进行的map任务都重置为空闲,重新调度,对应的reduce-worker若已经执行则重新执行,若未执行则从新指定的map-worker读取数据;而失败reduce-worker则不需要执行已经完成的reduce任务;
map-worker已完成的map任务输出存储在故障机器的本地磁盘上,因此即使完成了当map-worker失败时也需要重新执行;
master故障
- 处理:master维护着记录各个任务、各个程序的状态的数据结构,并定期写入这些数据结构的检查点,出现故障时从最后的检查点状态开始新的程序副本
MapReduce的优化
缺陷一:最后几个map或reduce任务中的某些需要异常长的时间才能完成
- 优化:备份任务,当MapReduce操作接近完成时,master安排剩余正在进行的任务备份执行,当主执行或备份执行完成时,将该任务标记为完成
缺陷二:用户代码的错误导致map或reduce函数在某些kv记录上总是崩溃
- 优化:尝试修复,如果不行的话就跳过记录,做法是在每个woker安装信号处理器,当捕获到错误时向master发送udp数据包,master发现在某个特定记录上不止一次失败时,就指示在下次重新执行任务时跳过记录
缺陷三:map-worker读取相应的输入分片需要通过网络与存储数据的服务器进行大量通信
- 优化:避免使用网络,将GFS与MapReduce混合运行在一组服务器中,当GFS将大文件拆分成64MB的块分散存储在各个服务器上,并保存多个副本时,master会找出输入分片具体存放在哪些GFS服务器上,并把对应那个输入分片的map任务调度到同一台服务器上,或尽量靠近输入分片
缺陷四:某些情况下,每个map任务产生的key值存在明显重复(比如单词计数器产生多条<"w",1>的记录
- 优化:在数据通过网络发送之前对其使用conbiner函数进行部分合并,这个函数与reduce函数的代码完全一致,唯一不同在于conbiner函数是将数据输出到中间文件,而reduce函数是将数据写入到最终输出文件