介绍
MapReduce是处理和产生大数据集的编程模型。用户先使用map函数接受一个KV对,生成中间的KV对,再将相同key的值合并,送到reduce函数处理。
模型需要考虑的问题
- 并发处理
- 容错处理
- 数据分布处理
- 负载均衡
- 其它
编程模式
map函数:输入一对kv,输出中间kv。
reduce函数:接受map函数输出的中间kv,并且处理相同key的value集合,输出0个或者1个值。
实现
一、整体流程图
二、步骤:
- 先将输入文件分成M块,每块大概16M到60M(根据参数决定),再在集群中执行处理程序。
- 程序由主控任务master,实际处理任务worker组成。worker分为map任务和reduce任务,这里总共由M个map任务和R个reduce任务。
- map接受分配到的输入数据块,并将数据解析成key/value对传给map函数处理,生成中间key/value并暂时缓存到内存。
- 定时的将上步生成的中间key/value刷新到磁盘,并且通过分区函数分成R个区,然后将这些分区的位置信息发送回master。master再将分区的位置信息发送给reduce的worker。
- 当reduce任务接收都来自master发送的中间key/value位置信息时,它通过rpc向map任务读取磁盘上的数据,读取完数据后需要先排序,这样把相同key的key/value都整合在一起,如果数据太大则需要外排序。
- reduce任务再把排好序的key/value集合进行计算处理,输出结果到文件(总共会有R个文件)。
- 当map和reduce任务都完成后,返回用户程序。
三、实现的关键点
- master的数据结构:它需要保存map和reduce任务的状态(idle,
in-progress 或者 completed),并且识别不同worker任务。master需要接收并保存map任务处理完成的中间值位置信息,并且发送到reduce任务。 - 容错考虑:worker失效考虑,master会定期ping worker,如果没有返回则认为是失效了,对于map任务如果失效,map任务执行完成则master需要重新分配它执行的任务,因为它产生的中间值位置会丢。对于reduce任务失效且执行完成则无需再次执行,因为它已经输出到文件中。master失效考虑,在 master 中,定期会设定 checkpoint,写出 master 的数据结构。如果 master 任务失效了,可以从 上次最后一个 checkpoint 开始启动另一个 master 进程。
- 存储位置:一般保存在本地磁盘通过GFS来管理。
- 任务粒度:map阶段拆成M块,reduce阶段拆成R块,M+R应该比worker的数量多得多,通常的比例大概是:M=20000,R=5000,worker数量2000
- 备用任务:对一些延时较长的任务(比如IO缓慢,网络延迟等导致),使用备用任务来执行。
四、实现中一些优化或技巧(或者称为工程最佳实践)
- 分区函数设计:主要是对分区粒度的把握,比如处理url时,有时是以url来分区,有时需要以hostname来分区
- key顺序保证:key在分区中应该处理成有序的
- combiner函数:合并map处理结果,再通过网络发送
- 输入和输出类型
- 边界效应
- 跳过损坏的记录
- 本地执行
- 状态信息
- 计数器