【翻译】6.824 lab1 (自用不负责)

简单记录一下,方便自己查看

开始实验

先用git下载实验的代码框架

$ git clone git://g.csail.mit.edu/6.824-golabs-2020 6.824

它提供的src/main/mrsequential.go 是一个顺序mapreduce实现,在单进程中执行map和reduce操作1次。

mrapps/wc.gomrapps/indexer.go是两个MapReduce应用。

举例运行wc.go

$ 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
...

mrequential.go将其输出保留在文件mr-out-0中。 它的输入来自名为pg-xxx.txt的文本文件。

可以随意从mrequential.go借用代码。

任务

实现一个分布式MapReduce,它由两个程序(master程序和worker程序)组成。
它将只有一个master进程以及一个或多个并行执行的worker进程。
在真实系统中,工作人员将在多台不同的机器上运行,但在本实验中,将在一台机器上运行它们。
worker通过RPC远程调用与Master对话。
每个Worker进程将向Master进程请求一个任务,从一个或多个文件读取任务的输入,执行任务,并将任务的输出写入一个或多个文件。
如果一个Worker没有在合理的时间内完成任务(本实验规定10秒),Master应该将该任务交给另一个Worker。

Master和Worker的main例程在main/mrmaster.gomain/mrworker.go中,不要改动这些程序。
需要在mr/master.go,mr/worker.gomr.rpc.go中实现自己的代码。

举例在单词统计wc.go这个MapReduce应用程序上运行代码:

  • 当前在main目录下,需要确保word-count插件是新构建的:
$ go build -buildmode=plugin ../mrapps/wc.go 

-删除原来的输入(可能不存在),执行master代码

$ rm mr-out*
$ go run mrmaster.go pg-*.txt
  • 在多个窗口中运行worker代码
$ go run mrworker.go wc.so
  • 当worker和master都完成,在mr-out-xxx查看输出。输出文件的排序并集应与顺序输出匹配,用cat命令查看
$ cat mr-out-* | sort | more
A 509
ABOUT 2
ACT 8
...

main/test-mr.sh中有一个测试脚本,测试在给定pg-xxx.txt文件作为输入的情况下,检查wc和indexer MapReduce应用程序是否产生正确的输出。
这些测试还检查自己的实现是否并行运行Map和Reduce任务,以及Worker能否在运行任务崩溃时恢复。

如果现在直接运行测试脚本,他将会一直运行,因为master死循环。

$ cd ~/6.824/src/main
$ sh test-mr.sh
*** Starting wc test.

可以在mr/master.go的Done函数中更改ret:=falseret:=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软件包可能会有一些类似如下的提示,忽略这些信息

rpc.Register: method "Done" has 1 input parameters; needs exactly three

一些规则:

  • map阶段应将中间键划分为用于nReduce reduce任务的存储桶,其中nReducemain/mrmaster.go传递给MakeMaster()的参数。

  • Worker实现应将第X个reduce任务的输出放在文件mr-out-X中。

  • 一个mr-out-X文件的每个Reduce函数输出应包含一行。 以Go中“%v%v”格式输出键和值。 在main/mrsequential.go中查看注释为“这是正确的格式”的行。 如果偏离此格式太多,则测试脚本将失败。

  • 可以修改mr/worker.go、mr/master.go和mr/rpc.go。可以临时修改其他文件进行测试,但请确保使用原始版本进行最终测试。

  • worker应该将中间映射输出放在当前目录中的文件中,这样稍后worker可以将它们读取他们作为Reduce任务的输入。

  • main/mrmaster.go期望mr/master.go实现Done()方法,该方法在MapReduce作业完全完成时返回true,结束mrmaster.go程序。

  • 作业完全完成后,Worker进程应退出。一种简单的实现方法是使用call()的返回值:如果Worker进程无法联系Master进程,则可以假定Master进程已经退出,因为任务已经完成,因此worker进程也可以终止。根据该设计,Master可以交给Worker的“请退出”的伪任务会很有帮助。

提示

  • 开始任务的一种方法是修改mr/worker.goworker(),以便向Master发送请求任务的RPC。然后修改master以响应一个尚未启动的映射任务的文件名。然后修改Worker以读取该文件并调用应用程序Map函数,如mrequential.go中所示。

  • 使用Go插件包在运行时从名称以.so结尾的文件中加载应用程序Map和Reduce函数。

  • 如果更改了mr/目录中的任何内容,则可能需要使用类似于go build-buildmode=plugin../mrapps/wc.go的命令重新构建MapReduce插件。

  • 本实验的worker依赖于共享文件系统。 当所有worker在同一台机器上运行时,这很简单,但是如果worker运行在不同的机器上,则需要GFS这样的全局文件系统。

  • 中间文件的合理命名约定是mr-X-Y,其中X是Map任务编号,Y是Reduce任务编号。

  • worker的map任务代码将需要一种方法来存储文件中的中间键/值对,这种方法可以在reduce任务期间正确读取。一种可能是使用Go的encoding/json包。要将键/值对写入JSON文件,请执行以下操作:

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)
  }
  • Worker的map部分可以使用ihash(Key)函数(在worker.go中)为给定的键选择Reduce任务。

  • 可以从mrequential.go窃取一些代码,用于读取Map输入文件,对Map和Reduce之间的中间键/值对进行排序,以及在文件中存储Reduce输出。

  • 作为RPC服务器的master将是并发的;不要忘记锁定共享数据。

  • 使用Go的race检测器,与go build -racego run -race一起使用。 test-mr.sh的注释展示了如何为测试启用race检测器。

  • worker有时需要等待,例如 在最后一个map任务完成之前,reduce无法开始。一种可能是worker定期向master请求工作,在每次请求之间用time.Sleep()休眠。另一种方法是,Master中的相关RPC处理程序有一个等待的循环,可以是time.Sleep(),也可以是sync.Cond。GO在其自己的线程中为每个RPC运行处理程序,因此一个处理程序正在等待的事实不会阻止主处理程序处理其他RPC。

  • Master无法可靠地区分崩溃的worker,活着的但由于某种原因停工的worker和执行但速度太慢而无法使用的worker。可以让master等待一段时间,然后放弃并将任务重新分配给不同的worker。对于本实验,让master等待10秒,之后,master应该假定工人已经死亡(当然,它可能没有死)。

  • 要测试崩溃恢复,可以使用mrapps / crash.go应用程序插件。 它在Map和Reduce函数中随机退出。

  • 为了确保在崩溃时没有人观察到部分写入的文件,MapReduce的论文提到了使用临时文件并在完全写入后自动重命名的技巧。可以使用ioutil.TempFile创建临时文件,使用os.Rename自动重命名它。

  • test-mr.sh运行子目录mr-tmp`中的所有进程,因此,如果出现问题,并且希望查看中间文件或输出文件,请在此处查找。

posted @ 2020-06-19 10:06  Greenty  阅读(1634)  评论(0编辑  收藏  举报