MapReduce模型

MapReduce模型

该模型对应的是MapReduce: Simplified Data Processing on Large Clusters论文中提出的模型。

mr模型基于分布式文件系统和集群,高吞吐但也存在高延迟的大数据处理模型,map和reduce的思想很值得借鉴。

map和reduce任务可以总结为:

  • map:(k1, v1) => list (k2, v2).

  • reduce:(k2, list(v2)) => list(v2).

MR流程

  1. 将输入文件拆分为大小(由用户定义)相等的M份split,在集群中的每一台机器都fork一份用户代码(用户代码分发),包含master(代码和worker不同)和worker。

  2. master有M个map任务和R个reduce任务分配,master从空闲的workers中选出一部分workers做map或reduce任务。

  3. map worker读取一个spilt(以流的形式),从中解析出kv对,输入到map函数,得到中间kv对,并将其缓存到内存中。

  4. map worker定期将缓存的kv对写入local文件系统,并根据partition函数分成R份,并保存在R个临时输出文件中。当map任务完成时,map worker将R个临时文件在local文件系统的位置发送给master,master将R个文件位置记录到指定的数据结构里,随后将其发送给reduce worker。

  5. master通知reduce worker步骤4中的磁盘位置,reduce worker通过远程调用读取数据。读取到所有数据后,reduce worker按key大小进行排序,使得key相同的kv对都在一起。

    为什么要排序(一般使用外部排序,数据量太大)?

    排序能让key相同的kv对在一块,且由于输出有序,reduce函数的输出也能够很简单的做到有序。

  6. reduce遍历kv对中包含的key,将key和其对应的value集合输入到reduce函数中,并将函数输出结果保存到临时输出文件中。(原子操作)当任务完成,reduce worker将临时文件append到该partition的最终输出文件(保存在global文件系统)。

  7. 当所有的map和reduce任务都完成了,master就会唤醒用户进程(mr是阻塞的),返回R个输出文件。

    R个输出文件一般不需要合并到一起,通常会将其作为其他mr任务或分布式程序的输入。

容错机制

论文中,使用心跳机制检查是否故障:每过一段时间,master都会ping每一个worker,若一段时间过后都没有收到回复,将其标记为故障。

不同的机器发生故障,故障恢复的机制也不同。

  • 当worker故障:已完成的map任务需要重做,因为map任务的输出是保存在local文件系统,已经无法访问了;已完成的reduce任务无需重做,因为reduce任务的输出保存在global文件系统中。当map worker A故障了,worker B接替A的工作,master会通知所有正在执行reduce任务的worker,从A中没有完全读取到的reduce任务将从B中读取。

  • 当master故障:master会定期备份mr过程的数据结构,当master故障后,可以根据上一个检查点备份恢复出一个新的master。但若是一个master,master故障会中止mr,并告知client。

当出现故障时,mr的输出结果是否能保证和没有故障一致?

  • 若map和reduce函数都是确定性函数(输入确定,输出也确定),mr可以保证即使出现故障,最终的结果也和没有出现故障的结果一致。
    • map worker完成map任务时,会向master发送包含R个临时文件名称的消息,master收到后,若该map任务已经完成时,忽略这条消息,否则,将其记录到数据结构中。
    • reduce worker完成reduce任务时,会原子化地将临时文件改名为最终输出文件。当同一个reduce任务由多个机器完成时,会产生多个重命名调用,通过原子化重命名操作,保证结果只包含一个reduce任务的输出。
  • 若map和reduce函数都是非确定性函数:因为最终R个文件是经由M个map任务组合而来,当出现故障时,R个文件中的一部分是重做过的,因此不能保证结果和没有故障一致。

任务分配

任务分配给哪台机器

mr任务通常都是在分布式文件系统上运行,在分布式系统中,网络带宽很紧缺。因此,master在分配map和reduce任务时会考虑机器的位置信息,map任务优先分配到包含输入文件副本的机器上,或位置靠近的机器。

任务粒度:M和R多大?

理想情况下,M和R应该尽可能大于机器数量,可以实现更好的动态负载均衡和加速故障恢复。

但M和R也不能太大,master在调度map和reduce worker时,时间复杂度为O(M+R),空间复杂度(map和reduce任务对只需大概一个字节,很小)为O(M*R),用户经常会限制R的大小,因为R个输出文件最终会合并成1个。

M一般设为使单个map任务数据大小为16~64MB的值,R设为机器数量的小倍数(如2,3)。

特定情况下的优化

为适应不同应用场景,mr有一些机制可以进行调整。

备份任务

当一个机器在执行map或reduce任务花了异常长的时间,mr的总体运行时间会被延长。

解决方案:当mr快完成时,master调度几个worker来执行剩余的任务作为备份,当有worker完成时,该任务就标记为完成。

partition函数

为使得map worker在划分输出结果时,保证结果平衡地分布在每一份中,partition函数默认使用hash值(hash_val mod R),但对于特定的结果(如URL),使用其他函数可能效果更好。

combine函数

在某些情况下,map任务会产生很多明显重复的中间kv对,比如word count的map任务,会产生大量key为单词,value为1的kv对,我们可以定义一个combine函数做一部分数据合并的工作。

通常,combine函数和reduce函数相同,唯一的区别就是combine函数的的输出是中间kv对,reduce函数的输出是最终结果。

输入输出类型

mr内置了常见类型的reader,如text格式的文件,一行为一个kv对,key为行号,value为该行的内容。

我们可以自定义reader来使得mr读取一个新的类型。

输出和输入类似,可以通过自定义writer来输出一个新的类型。

额外输出

两阶段提交:可以参考MySQL中binlog和redo log的提交机制。

mr没有设置用于单个任务输出多个文件的两阶段提交,因此若需要在map或reduce任务中生成额外文件,比如用于容错恢复的log,我们需要自己来保证额外输出的正确性,如原子性和幂等性。

跳过错误记录

有些记录会导致map或reduce函数崩溃,若不能修复这个bug且能容忍一部分错误记录,那么mr就会跳过错误记录。

实现:每一个worker都有一个处理错误的handler,当map任务或reduce任务出现错误记录、引发错误时,handler会向master上报,master会记录下该记录标志,当再次发生由该记录引发的错误时,master会在下一次重做时通知worker跳过该记录。

调试

为方便调试,mr的所有环节都可以在本地运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值