MIT6.824 Lab1 MapReduce

Introduction
  本次实验主要是用go语言来实现1个MapReduce库,并且了解分布式系统的容错机制,推荐先看一下MapReduce的论文[MapReduce]
  主要机制如下图:
  这里写图片描述
  Map worker读入1个文件,处理后生成n(reduce worker数目)个中间文件,然后每个Reduce worker读取其对应的所有中间文件,处理后生成1个结果文件,最后n个结果文件可以merge成1个最终结果文件。
  
Software
  由于实验中的代码是由go语言实现的,所以需要先去看看go的基本语法以及相关教程,链接在这里Go(ps:需要翻墙/(ㄒoㄒ)/~~)
  使用git来下载实验的代码,repository为git://g.csail.mit.edu/6.824-golabs-2016。然后再去安装golang的编译器即可,这里实验中使用的是1.5版本。

Preamble: Getting familiar with the source
  mapreduce包提供了1个简单的Map/Reduce库的串行实现。正常应用应该调用Distributed函数[master.go]来启动1个任务,但是可以通过调用Sequential函数[master.go]来进行debug。
  mapreduce实现流程:
  1、应用提供一些输入文件,1个map函数,1个recude函数,reduce worker的数目(nReduce)。
  2、建立1个master节点,它启动1个RPC server(master_rpc.go),然后等待workers来注册(使用RPC call Register函数[master.go]). 当worker可用时(在第4、5步骤),schedule函数[schedule.go]决定如何分配任务到worker以及如何处理worker的failures。
  3、master节点认为每个输入文件对应1个map任务,为每个任务至少调用1次doMap函数[common_map.go]。每次调用doMap函数会读取合适的文件,并调用map函数来处理文件内容,为每个map文件生成nReduce个文件。
  4、master节点接下去为每个reduce任务至少调用1次doReduce函数[common_reduce.go]。doReduce函数收集nReduce个reduce文件,然后调用reduce函数处理这些文件,产生nReduce个结果文件。
  5、master节点调用mr.merge函数[master_splitmerge.go],来整合nReduce个结果文件成1个最终文件。
  6、master节点发送1个Shutdown的RPC调用到每个worker,来关闭它们的RPC server。

Part I: Map/Reduce input and output
  首先是实现Map/Reduce的串行执行,在给出的代码中缺少2个关键的片段:将map任务的输出分割成nReduce个文件的 doMap函数[common_map.go],以及将reduce任务的nReduce个输入整合成1个文件的doReduce函数[common_reduce.go]。
  为了帮助测试你的代码是否正确,实验中还提供了test文件[test_test.go]来测试。关于go test命令的说明可以看这里go test

go test -run Sequential mapreduce/... 

  run参数表示测试mapreduce文件夹下test_test.go文件中以Test开头包含Sequential的测试函数,即TestSequentialSingle和TestSequentialMany函数。这里针对TestSequentialSingle来分析一下具体流程,有助于编写doMap和doReduce函数。

func TestSequentialSingle(t *testing.T) {
    mr := Sequential("test", makeInputs(1), 1, MapFunc, ReduceFunc)
    mr.Wait()
    check(t, mr.files)
    checkWorker(t, mr.stats)
    cleanup(mr)
}
func Sequential(jobName string, files []string, nreduce int,
    mapF func(string, string) []KeyValue,
    reduceF func(string, []string) string,
) (mr *Master) {
    mr = newMaster("master")
    go mr.run(jobName, files, nreduce, func(phase jobPhase) {
        switch phase {
        case mapPhase:
            for i, f := range mr.files {
                doMap(mr.jobName, i, f, mr.nReduce, mapF)
            }
        case reducePhase:
            for i := 0; i < mr.nReduce; i++ {
                doReduce(mr.jobName, i, len(mr.files), reduceF)
            }
        }
    }, func() {
        mr.stats = []int{
  len(files) + nreduce}
    })
    return
}

  首先通过Sequential函数[master.go]来创建1个master结构体,然后运行1个goroutine来执行mr.run函数。其中master结构体的定义如下:

type Master struct {
    sync.Mutex

    address         string
    registerChannel chan string
    doneChannel     chan bool
    workers         []string // protected by the mutex

    // Per-task information
    jobName string   // Name of currently executing job
    f
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值