MapReduce 包含两种操作,Map 和 Reduce。
其中 Map 是按照用户定义的方式,将字符串(通常是文本内容)转化成一组键值对。这个操作虽然叫做 Map,但并不是一定是真正意义上的映射。转化出的键值对更应该叫做二元组,因为多个键值对可以有相同的 Key ,甚至可以 Key 和 Value 均相同。
Reduce 则是操作 Map 得到的键值对组。将其中 Key 相同键值对的全部 Value 按照用户定义的方式进行合并。
MapReduce 的典型应用是词频统计。
分布式处理一个分布式的 MapReduce 系统,能将 Map 和 Reduce 操作分配给集群的不同设备(Worker)来处理。
MapReduce 系统,需要处理多个文件的 Map 操作和 Reduce 操作。使用分布式系统,将 MapReduce 分成多个任务来执行。每个文件的 Map 作为单独的任务,由不同的机器来进行。在完成所有 Map 操作后,将结果汇总,开始 Reduce 操作(因为每个文件产生的键值对都可能对最终结果产生影响,所以必须进行完 Map 才能开始 Reduce)。
Reduce 可以将键值对按照 Key 的哈希值分组进行。每个 Worker 的 Reduce 任务是处理一组的键值对的 Reduce。这样,就将一个大的 MapReduce 任务拆分为了许多个可以并发执行的子任务,实现了分布式处理。
整体架构分布式处理 MapReduce,需要用到整体的协调者(coordinator)。集群中的设备除了一个协调者,其余都是工作者(Worker)。协调者负责进行集群的整体调度,工作者负责执行协调者分配的具体 Map 或 Reduce 工作。
每个工作者一旦空闲,就向协调者请求任务。协调者记录哪些任务已经分配,哪些任务已经完成。当全部 Map 任务都完成,就可以开始分配 Reduce 任务。当全部 Reduce 任务都完成,就可以宣布结束。
通信方式使用 rpc 交互(golang的rpc包)。由于测试是在一台电脑上进行,因此rpc socket设为本地的一个目录。通过这个目录,实现进程间的通信。
同步方式通过协调者调度,给工作者分配任务。所有工作者都只与协调者通信,协调者通过锁的方式,保证自身资源不产生并发错误。
程序模块说明 协调者(Coordinator)启动一个协调者,需要告诉它所有Map的源文件,以及中间结果分成的组数(nReduce)。前者是Map任务的数量,后者是Reduce任务的数量。协调者记录每个 Map 任务和 Reduce 任务的状态,包括是否已经分配,是否已经完成。
工作分配当收到工作者向协调者发送的工作分配请求时,如果还有未分配的 Map 任务,则及时分配 Map 任务。如果 Map 都已经分配但未全部执行完,就让工作者先进行等待。如果Map都已经执行完但还有Reduce未分配,则让分配Reduce任务。如果Reduce都已经分配,则告诉工作者结束工作。如果一项 Map 或 Reduce 操作分配给一个 Worker 十秒后,Worker 还没有反馈运行结束,就认为这个 Worker 发生了崩溃,将其任务设为还未分配。
分配任务时,要给出输入文件的地址或任务的相应编号。
工作完成当工作者通知协调者工作完成时,协调者将其任务设为已完成。如果是Map任务完成,需要记录中间结果写入的文件名。如果所有Map或Reduce任务都已经完成,则可以开始下一项任务或通知所有工作者任务结束。
Map结果查询当收到工作者对于Map结果的查询时,这时所有Map都已经结束,工作者正在执行Reduce任务。工作者需要提供其Reduce操作的操作号。协调者将此前记录的所有Map结果中,与此操作号对应所有文件名一起返回。
工作者(Worker)启动一个工作者,只需要传入用户给出的Map函数和Reduce函数即可。
工作请求工作者在空闲时间,每隔一秒向协调者请求分配工作,除非协调者告知所有工作结束。
拿到Map工作后,工作者就读出输入文件的内容,并使用Map函数进行计算,得到键值对组。然后,将每个键值对的Key进行哈希并对组数(nReduce)取模作为组号,将这一键值对写入这一组号对应的文件中。
拿到Reduce工作后,工作者先向协调者查询这一工作所需的全部Map结果。拿到以后,将这些文件的内容读出来,按照拿到每个Key对应的Value集合,进行Reduce操作。
工作完成在Map或Reduce操作完成后,工作者需要向协调者发rpc,告知任务已经完成。传递的消息中需要包含任务的编号。如果是Map任务,还应当包含结果写入的文件路径。
Map结果查询当工作者需要进行Reduce操作时,需要查询此前的Map结果。向协调者发送Map结果查询的rpc请求,包含自身的Reduce工作编号。协调者会返回工作编号对应的全部Map结果。
运行结果使用了6.824课程提供的自动测试。需要在linux/MacOS进行测试(因为需要unix文件系统)



