6.824-Lab 1: MapReduce

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上工作。

macOS

你可以使用Homebrew安装Go。安装Homebrew后,运行brew install go。

Linux

根据你的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上工作。如果你感到冒险,你可以尝试在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.gomain/mrworker.go中;不要更改这些文件。你应该将你的实现放在mr/master.gomr/worker.gomr/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中。测试检查wcindexer 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.gomr/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

忽略这些消息。 一些规则:

  • map阶段应该将中间键分成nReduce个reduce任务的桶,其中nReduce是main/mrmaster.go传递给MakeMaster()的参数。 worker实现应该将X'th reduce任务的输出放在名为mr-out-X的文件中。
  • 一个mr-out-X文件应该包含每个Reduce函数输出的一行。该行应该使用Go的“%v %v”格式生成,调用键和值。在main/mrsequential.go中查看注释“这是正确的格式”。如果你的实现与这种格式偏差太大,测试脚本将会失败。
  • 你可以修改mr/worker.go、mr/master.go和mr/rpc.go。你可以临时修改其他文件进行测试,但请确保你的代码与原始版本一起工作;我们将使用原始版本进行测试。
  • worker应该将中间Map输出放在当前目录的文件中,以便你的worker稍后可以将它们作为Reduce任务的输入读取。
  • main/mrmaster.go期望mr/master.go实现一个Done()方法,当MapReduce作业完全完成时返回true;那时,mrmaster.go将退出。
  • 当作业完全完成时,worker进程应该退出。实现这一点的一种简单方法是使用call()的返回值:如果worker未能联系到master,它可以假设master已经退出,因为作业已经完成,所以worker也可以终止。根据你的设计,你可能还会发现让master给workers一个“请退出”的伪任务很有帮助。

提示

  • 开始的一种方法是修改mr/worker.go的Worker(),发送一个RPC到master请求一个任务。然后修改master以响应尚未开始的map任务的文件名。然后修改worker以读取该文件并调用应用程序Map函数,如mrsequential.go中所示。
  • 应用程序Map和Reduce函数是使用Go插件包在运行时加载的,从以.so结尾的文件中加载。
  • 如果你更改了mr/目录中的任何内容,你可能必须使用类似go build -buildmode=plugin ../mrapps/wc.go的命令重新构建你使用的任何MapReduce插件
  • 这个实验依赖于workers共享一个文件系统。当所有workers都在同一台机器上运行时,这很简单,但如果workers在不同的机器上运行,就需要像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部分可以使用worker.go中的ihash(key)函数为给定键选择reduce任务。
  • 你可以从mrsequential.go中窃取一些代码,用于读取Map输入文件,用于在Map和Reduce之间排序中间键/值对,以及用于将Reduce输出存储在文件中。
  • 作为RPC服务器的master将是并发的;不要忘记锁定共享数据。
  • 使用Go的竞态检测器,使用go build -race和go run -race。test-mr.sh中有一个注释,向你展示如何为测试启用竞态检测器。
  • Workers有时需要等待,例如,在最后一个map完成之前,reduces不能开始。一种可能性是workers定期向master请求工作,在每次请求之间使用time.Sleep()睡眠。另一种可能性是让master中的相关RPC处理程序有一个循环等待,使用time.Sleep()或sync.Cond。Go为每个RPC的处理程序运行在自己的线程中,所以一个处理程序的等待不会阻止master处理其他RPC。
  • master无法可靠地区分崩溃的workers、出于某种原因停滞的活着的workers和执行过慢以至于无用的workers。你能做的最好的是让master等待一段时间,然后放弃并将任务重新分配给另一个worker。对于这个实验,让master等待十秒钟;之后master应该假设worker已经死了(当然,它可能没有)。
  • 要测试崩溃恢复,你可以使用mrapps/crash.go应用程序插件。它在Map和Reduce函数中随机退出。
  • 为了确保在崩溃发生时没有人观察到部分写入的文件,MapReduce论文提到了使用临时文件并在完全写入后原子地重命名它的技巧。你可以使用ioutil.TempFile创建一个临时文件,使用os.Rename原子地重命名它。
  • test-mr.sh在mr-tmp子目录中运行所有进程,所以如果出了问题,你想查看中间或输出文件,请在那里查看。

提交程序

提交之前,请再次运行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

相关推荐

  1. 6.824-Lab 1: MapReduce

    2024-02-07 23:12:02       56 阅读
  2. 【MIT 6.5840/6.824】Lab1 MapReduce

    2024-02-07 23:12:02       23 阅读
  3. csapp proxy lab part 1

    2024-02-07 23:12:02       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-07 23:12:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-07 23:12:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-07 23:12:02       82 阅读
  4. Python语言-面向对象

    2024-02-07 23:12:02       91 阅读

热门阅读

  1. 查看jar包编译的jdk版本

    2024-02-07 23:12:02       56 阅读
  2. Android:View&Adapter

    2024-02-07 23:12:02       57 阅读
  3. Python调用cuRandSobol生成Sobol

    2024-02-07 23:12:02       47 阅读
  4. SQL基础

    2024-02-07 23:12:02       43 阅读
  5. Oracle的权限

    2024-02-07 23:12:02       46 阅读
  6. 记录 | python tqdm用法_图片读取进度

    2024-02-07 23:12:02       62 阅读
  7. leetcode524 通过删除字母匹配到字典里最长单词

    2024-02-07 23:12:02       57 阅读
  8. C++中的作用域

    2024-02-07 23:12:02       59 阅读
  9. c#使用Minio(3.1.13版本)

    2024-02-07 23:12:02       52 阅读
  10. C语言中的变量与函数详解

    2024-02-07 23:12:02       52 阅读
  11. Top 20 Docker 面试题(附答案)

    2024-02-07 23:12:02       54 阅读
  12. 2023-12蓝桥杯STEMA 考试 Python 中高级试卷解析

    2024-02-07 23:12:02       58 阅读