lab1链接:6.824 Lab 1: MapReduce (mit.edu)
在这个实验中,你将构建一个MapReduce系统。你将实现一个工作进程(worker process),调用应用程序的Map和Reduce函数,并处理文件的读写,以及一个主进程(master process),分配任务给工作进程并处理失败的工作进程。你将构建的系统与MapReduce论文中描述的相似。
你必须自己编写你提交的6.824课程的所有代码,除了我们作为作业一部分提供给你的代码。你不允许查看其他人的解决方案,也不允许查看前几年的解决方案。你可以与其他学生讨论作业,但你不可以查看或复制彼此的代码。这条规则的原因是我们相信通过自己设计和实现实验的解决方案,你将学到最多。
请不要发布你的代码或使其对当前或未来的6.824学生可用。github.com仓库默认是公开的,所以请不要将你的代码放在那里,除非你将仓库设为私有。你可能会发现使用MIT的GitHub很方便,但请确保创建一个私有仓库。
你将使用Go语言实现这个实验(以及所有实验)。Go网站包含大量教程信息。我们将使用Go版本1.13对你的实验进行评分;你也应该使用1.13版本。你可以通过运行go version来检查你的Go版本。
我们建议你在自己的机器上工作,这样你就可以使用你已经熟悉的工具、文本编辑器等。或者,你也可以在Athena上工作。
你可以使用Homebrew安装Go。安装Homebrew后,运行brew install go。
根据你的Linux发行版,你可能能够从包仓库中获取最新版本的Go,例如通过运行apt install golang。否则,你可以从Go的网站手动安装二进制文件。首先,确保你运行的是64位内核(uname -a应该提到“x86_64 GNU/Linux”),然后运行:
$ wget -qO- https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz | sudo tar xz -C /usr/local
你需要确保/usr/local/bin在你的PATH中。
实验可能无法直接在Windows上工作。如果你感到冒险,你可以尝试在Windows子系统中运行Linux,并按照上述Linux指南操作。否则,你可以退回到Athena。
你将使用git(一个版本控制系统)获取初始实验软件。要了解更多关于git的信息,请查看Pro Git书籍或git用户手册。获取6.824实验软件:
$ git clone git://g.csail.mit.edu/6.824-golabs-2020 6.824
$ cd 6.824
$ ls
Makefile src
$
我们为你提供了一个简单的顺序mapreduce实现,在src/main/mrsequential.go中。它一次一个地运行maps和reduces,只在一个进程中。我们还为你提供了一些MapReduce应用程序:word-count在mrapps/wc.go中,文本索引器在mrapps/indexer.go中。你可以按照以下方式顺序运行word count:
$ cd ~/6.824
$ cd src/main
$ go build -buildmode=plugin ../mrapps/wc.go
$ rm mr-out*
$ go run mrsequential.go wc.so pg*.txt
$ more mr-out-0
A 509
ABOUT 2
ACT 8
...
mrsequential.go将其输出留在名为mr-out-0的文件中。输入来自名为pg-xxx.txt的文本文件。
随意借用mrsequential.go中的代码。你还应该查看mrapps/wc.go,以了解MapReduce应用程序代码的样子。
你的任务是实现一个分布式MapReduce,由两个程序组成,master和worker。将只有一个master进程,以及一个或多个并行执行的worker进程。在一个真实的系统中,workers会在一堆不同的机器上运行,但对于这个实验,你将在一台机器上运行它们全部。workers将通过RPC与master通信。每个worker进程将向master请求一个任务,从一个或多个文件中读取任务的输入,执行任务,并将任务的输出写入一个或多个文件。如果一个worker在合理的时间内(对于这个实验,使用十秒钟)没有完成其任务,master应该注意到,并将相同的任务分配给另一个worker。 我们已经给你一些代码来开始。master和worker的“main”例程分别在main/mrmaster.go和main/mrworker.go中;不要更改这些文件。你应该将你的实现放在mr/master.go、mr/worker.go和mr/rpc.go中。
以下是如何在word-count MapReduce应用程序上运行你的代码。首先,确保word-count插件是最新构建的:
$ go build -buildmode=plugin ../mrapps/wc.go
在主目录中,运行master。
$ rm mr-out*
$ go run mrmaster.go pg-*.txt
mrmaster.go的pg-*.txt参数是输入文件;每个文件对应一个“split”,并且是一个Map任务的输入。 在一个或多个其他窗口中,运行一些workers:
$ go run mrworker.go wc.so
当workers和master完成后,查看mr-out-*中的输出。当你完成实验时,输出文件的排序联合应该与顺序输出匹配,如下所示:
$ cat mr-out-* | sort | more
A 509
ABOUT 2
ACT 8
...
我们为你提供了一个测试脚本,在main/test-mr.sh中。测试检查wc和indexer MapReduce应用程序在给定pg-xxx.txt文件作为输入时是否产生正确的输出。测试还检查你的实现是否并行运行Map和Reduce任务,以及你的实现是否从运行任务时崩溃的workers中恢复。
如果你现在运行测试脚本,它会挂起,因为master永远不会完成:
$ cd ~/6.824/src/main
$ sh test-mr.sh
*** Starting wc test.
你可以在mr/master.go的Done函数中将ret := false更改为true,以便master立即退出。然后:
$ sh ./test-mr.sh
*** Starting wc test.
sort: No such file or directory
cmp: EOF on mr-wc-all
--- wc output is not the same as mr-correct-wc.txt
--- wc test: FAIL
$
测试脚本期望在名为mr-out-X的文件中看到输出,每个reduce任务一个。空的mr/master.go和mr/worker.go实现不会产生这些文件(或做任何其他事情),所以测试失败。
当你完成时,测试脚本的输出应该如下所示:
$ sh ./test-mr.sh
*** Starting wc test.
--- wc test: PASS
*** Starting indexer test.
--- indexer test: PASS
*** Starting map parallelism test.
--- map parallelism test: PASS
*** Starting reduce parallelism test.
--- reduce parallelism test: PASS
*** Starting crash test.
--- crash test: PASS
*** PASSED ALL TESTS
$
你还会看到Go RPC包的一些错误,看起来像
2019/12/16 13:27:09 rpc.Register: method "Done" has 1 input parameters; needs exactly three
忽略这些消息。 一些规则:
enc := json.NewEncoder(file)
for _, kv := ... {
err := enc.Encode(&kv)
并且读回这样的文件: dec := json.NewDecoder(file)
for {
var kv KeyValue
if err := dec.Decode(&kv); err != nil {
break
}
kva = append(kva, kv)
}
提交之前,请再次运行test-mr.sh。
使用make lab1命令打包你的实验作业并将其上传到课程的提交网站,位于https://6824.scripts.mit.edu/2020/handin.py/。
你可以使用MIT证书或通过电子邮件请求API密钥首次登录。你登录后会显示你的API密钥(XXX),可以使用它通过控制台上传lab1,如下所示。
$ cd ~/6.824
$ echo XXX > api.key
$ make lab1