6.824第一次项目总结

要学习的三个目标,如何设计代码架构,如何由简入难的拆分任务,理解go的写法

如何由简入难的架构代码并实现

第一, mapreduce无非就是输入经map任务生成中间键值对放入中间文件中再经reduce处理。其中map分布在几台机器上,reduce也分布在几台机器上,具体schedule交由master.
那么要设计一个简单同时可供扩展的结构。我们可以先设计master,且只有这一台机器,调度map和reduce任务在这一台机器上执行
这样可以确认map和reduce实现的是否正确,同时暴露出schedule的接口,以供后续实现

master的数据结构,调度和运行

先设计master:

  1. 基础接口: 地址,保存的worker的地址,输入文件名,reduce的任务量,网络接口用来听worker的请求等等,
  2. 特定的设计,由于woker和master是并行的,要有一定的的机制能够使在worker工作时,master block的设计,此处采用 bool chan,当所有任务完成时发送消息给chan, master不在阻塞
    单机版要做的是master启动,运行
    master run需要的核心功能,文件输入, reduce数目,schedule接口,用来调度map和reduce, finishi接口,用来收尾。
    然后设计单机版线性执行,将schedule的接口实现成线性执行的map,reduce任务

    doMap的设计

    doMap类似于一个系统接口,它收到文件,利用用户定义的mapF函数将其转为键值对,将键值对存储到中间文件中,对中间文件进行规律性命名.
    doMap实现思路, 读取文件,利用mapF函数将读取的文件转成键值对,生成根据参数而决定的中间文件数目,利用hash将相关的键值对编码入向相关的文件,做一些收尾工作

    doReduce的设计

    doReduce的任务: 找到该reduce任务对应的文件,将其中内容解码出来,设计mapreduce论文中的字典,既收集同一个key的value,然后排序,设计输出文件,利用用户定义的reduceF函数进行处理,输出到输出文件中。

    考虑分布式的实现

    问题设计的方面: master如何动态的知道worker的存在,如何动态的根据worker存在完成任务的分配,如何确认的任务的完成,以及worker要如何并发的执行任务
    要学会考虑问题:我要解决怎样的问题,导致需要多线程,而不是有了多线程,要做什么 首先,master会动态的接收worker的注册信息,并将其传递给调度器,在调度器执行的过程中,依然需要动态接收有新注册的worker信息, 所以distributed的代码中,要有俩个线程,一个用来做网络的接听口,接听worker的注册信息,另一个用来执行主程序,主程序呢依然有俩个线程,一个用来传递新注册的worker信息,另一个用来调度.
    schedule的任务:
    原则:它所调度的所有woker任务完成后才能结束,他的执行完毕代表所有worker执行完毕
    要有接收新注册woker信息的渠道,
    要有block机制
    要有分配任务,执行任务,fault-tolerant的机制
    fault_tolerance的机制:如果有执行失败的任务号,将其回收重新分配, 所以程序构造思路:
    不断的读取任务号分配给worker,直到所有的任务被执行完毕
    这里不断的分配任务,回收任务使用loop,而loop主体可改变的方式采用chan(不知道是否还有其他方式),chan中存放任务号,那么就需要另一个线程为chan放置初始值,同时控制chan的close,这个线程也要接受所有任务都已完成的信息,这里采用waitGroup.
    再分配任务的loop中,每一次循环的都开启一个线程,用来完成任务,通过worker的channel和任务号的channel来进行交流。