6.824 Spring 2020 -- Lab 1: MapReduce

介绍:https://pdos.csail.mit.edu/6.824/labs/lab-mr.html

代码实现:https://github.com/bryson-davis/6.824-golabs-2020 (分支lab-1-mr)

实现目标

根据论文实现一个如下的map-reduce分布式系统

6.824 Spring 2020 -- Lab 1: MapReduce_第1张图片

 

根据论文和lab的要求,我们要实现一个系统,这个系统里面有master和worker,master负责分配任务,而worker负责执行任务,也就是分布式系统里面的集中式系统了。系统的功能是可以分布式地处理不同的文件内容,对内容进行统计。这样做的目的在于使用更多的机器来做更快地做更多的事情

整体流程和实现

我们介绍如下的几个概念:

  1. split,也就是切分,一般就是指将文件的内容进行切分成合适的块
  2. map任务,负责执行Map阶段,map的任务是将split之后的键值内容进行映射成一种中间的键值内容,并将键值内容根据键对reduce任务的数量的哈希结果,放入不同的桶中,每个桶都对应一个reduce任务的输入列表之一
  3. reduce任务,负责执行reduce阶段,每个reduce的任务,都是去读取对应每个map任务生成的键值内容(也就是对应自己的桶),然后将这些去键值内容进行整合
  4. worker,也就是执行机,负责请求任务和执行任务,任务有两种类型,分别是map类型任务和reduce类型任务
  5. master,负责分派任务和管理任务(超时等)

为了更加方便理解,我们以论文中的word count进行说明,这个例子的目的在于统计一堆文件中每个单词的个数,

  1. split,进行切分,如果文件内容不是很大,我们直接就使用各个文件做为一个块,不做任何处理,也就是split之后就是,那么如果我们有m个文件,也就对应有m个map任务了,这些任务是可以并发进行处理的
  2. map,每个map任务都会有一个属于自己的编号x,接收一个内容,初始化一个大小为nReduce(reduce的任务数)的桶buckets,读取content内容,每遇到一个单词就生成一个(映射规则),然后根据word与nReduce(reduce的任务数)进行哈希,得到一个桶序号y,并将这个单词放入buckets[y]中,等处理完后,将buckets内容保存至文件中,每个bucket对应一个文件,文件名为mr-x-y
  3. reduce,在上述m个map任务全部执行完成后,我们会得到m*n个中间文件(每个map任务会生成n个文件,当然有可能为空),编号为y的reduce任务,会依次读取mr-x-y文件的内容,其中x为迭代变量,从0到m-1,读取每个mr-x-y的内容之后,对内容进行排序,然后把文件的内容根据key进行整合,整合的规则是统计每个key出现的频次,得到,其中count表示每个key的数量,然后把内容保存到文件名为mr-out-y的文件中
  4. 最后,我们只需要把所有mr-out-y的内容合并成一个文件就是我们需要的内容了

master的流程视角

  1. master启动时,接收需要进行mapreduce的文件,每个文件会对应一个map任务,并进行等待,等待worker发送请求来请求任务
  2. 当worker发送请求来时,进行如下的任务调度操作:
    1. 查看是否还有map任务,有的话就分配map任务,并返回
    2. 如果map任务已经全部分配,且还没有完全执行结束,就进行等待
    3. 如果map任务已经全部分配,而且已经全部执行结束,就分配reduce任务
    4. 对reduce任务的调度逻辑与map相同
    5. 当所有的任务都已经执行结束,则整个流程结束
  3. master还需要负责接收来自worker的任务完成请求,表示某个任务已经完成,从而进行任务信息统计;而且还需要监控任务的执行,如果超过超时时间就直接进行重试

worker的流程视角

  1. worker启动后,会发送一个申请任务的请求,得到任务后,判断任务的类型
    1. 如果是map任务,就调用map函数进行处理
    2. 如果是reduce任务,就调用reduce函数进行处理
    3. 如果接收到无新任务,就直接退出
  2. 为了减少rpc通讯量,可以把当前任务执行完成的信息放到下次申请任务的请求,发送到master上

 

实验流程

1. 下载代码放到,把代码放到gopath目录下,比如你的gopath=/tmp/gopath的话,就把代码git clone到/tmp/gopath下面

2. 代码开发完成后,以测试wc的准确性,就在main目录下执行go build -buildmode=plugin ../mrapps/wc.go  然后启动master, go run mrmaster.go pg-*.txt,再启动worker,go run mrworker.go wc.so

 3. 完成test-mr.sh的测试,直接执行 sh test-mr.sh

  • 前两个测试是测试结果的准确性
  • 第三个是测试map task的并行性,也就是你的程序是否支持不同的map任务在不同的worker上执行
  • 第四个是测试reduce task的并行性,也就是你的程序是否支持不同的reduce任务在不同的worker上执行
  • 最后 一个是测试程序的容错性,当你的worker会延迟或者失败时,你的master是否可以重新进行任务的分配

 

参考实现

https://github.com/clatisus/MIT6.824DS/blob/master/src/mr/worker.go

你可能感兴趣的:(分布式,6.824)