设为首页 加入收藏

TOP

mit 6.824 lab1分析(一)
2023-07-23 13:30:33 】 浏览:71
Tags:mit 6.824lab1分析

6.824 lab1 笔记

1. 阅读论文

2. 官网rules & hints

2.1 rules

  1. map阶段每个worker应该把中间文件分成nReduce份,nReduce是reduce任务的数量
  2. worker完成reduce任务后生成文件名mr-out-X
  3. mr-out-X文件每行应该是"%v %v"格式,参考main/mrsequential.go
  4. worker处理完map任务,应该把生成的中间文件放到当前目录中,便于worker执行reduce任务时读取中间文件
  5. 当所有任务完成时,Done()函数应该返回true,使得coordinator退出
  6. 所有任务完成时,worker应该退出,方法是:
    1. 当worker调用rpc向coordinator请求任务时,连接不上coordinator,此时可以认为coordinator已经退出因为所有任务已经完成了
    2. 当worker调用rpc向coordinator请求任务时,coordinator可以向其回复所有任务已经完成

2.2 hints

  1. 刚开始可以修改mr/worker.go's ``Worker()向coordinator 发送一个RPC请求一个任务。然后修改coordinator回复一个文件名,代表空闲的map任务。然后worker根据文件名读取文件,调用wc.so-Map函数,调用Map函数可参考mrsequential.go`

  2. 如果修改了mr/目录下任何文件,应该重新build MapReduce plugins,go build -buildmode=plugin ../mrapps/wc.go

  3. worker处理完map任务后产生的中间文件命名格式mr-X-Y,x是map任务的编号,y是reduce任务编号。

    // 初始文件,通过命令行传入的,如
    // pg-being_ernest.txt pg-dorian_gray.txt pg-frankenstein.txt 
    // len(files) = 3 nReduce = 4
    // 中间文件  x:map任务的编号 y:reduce任务编号
    // mr-0-0 mr-1-0 mr-2-0
    // mr-0-1 mr-1-1 mr-2-1
    // mr-0-2 mr-1-2 mr-2-2
    // mr-0-3 mr-1-3 mr-2-3
    
  4. map任务存储数据到文件可以使用json格式,便于reduce任务读取

      // map
      enc := json.NewEncoder(file)
      for _, kv := ... {
        err := enc.Encode(&kv)
          
      // reduce
      dec := json.NewDecoder(file)
      for {
        var kv KeyValue
        if err := dec.Decode(&kv); err != nil {
          break
        }
        kva = append(kva, kv)
      }
    
  5. map阶段使用ihash(key)函数把key映射到哪个reduce任务,如某个worker取得了2号map任务,ihash("apple") = 1,那么就应该把该key放到mr-2-1文件中

  6. 可以参考mrsequential.go代码:读取初始输入文件、排序key、存储reduce输出文件

  7. coordinator是rpc server,将会被并发访问,需要对共享变量加锁

  8. 若当前未有空闲的map任务可以分配,worker应该等待一段时间再请求任务,若worker频繁请求任务,coordinator就会频繁加锁、访问数据、释放锁,浪费资源和时间。如使用time.Sleep(),worker可以每隔一秒发送一次请求任务rpc

  9. coordinator无法辨别某个worker是否crash,有可能某个worker还在运行,但是运行极其慢(由于硬件损坏等原因),最好的办法是:coordinator监控某个任务,若该任务未在规定时间内由worker报告完成,那么coordinator可以把该任务重新分配给其他worker,该lab规定超时时间是10s

  10. 为了确保某个worker在写入文件时,不会有其他worker同时写入;又或者是某个worker写入文件时中途退出了,只写了部分数据,不能让这个没写完的文件让其他worker看到。可以使用临时文件ioutil.TempFile,当写入全部完成时,再使用原子重命名os.Rename

  11. Go RPC只能传struct中大写字母开头的变量

  12. 调用RPC call() 函数时,reply struct应该为空,不然会报错

      reply := SomeType{}
      call(..., &reply)
    

3. 架构设计

3.1 RPC设计

在该lab中,我们需要两个RPC,一个是callTask RPC向coordinator请求一个任务,一个是callTaskDone RPC向coordinator报告某个任务的完成,以下皆在rpc.go中定义

  1. 首先定义一个枚举变量,表示coordinator给worker分配的任务类型,也可用来表示coordinator当前的phase

    type taskType int
    
    const (
        // map任务
    	mapType taskType = iota
        // reduce任务
    	reduceType
        // 当前没有空闲任务,请等待
        waitting
        // 已经完成全部任务,可以退出了
    	done
    )
    
  2. 定义拉取任务RPC的args和reply struct

    CallTaskArgs中不需要包含变量,只需要让coordinator知道该worker正在请求一个任务,coordinator会随机选择空闲任务进行分配填入CallTaskReply

    CallTaskReply包含以下变量:

    • FileName:map阶段,worker需要知道具体的文件名才能解析该文件
    • tp:指示该任务的具体类型
    • TaskID:worker将该变量放入CallTaskDoneArgs中,coordinator可以迅速定位Task[TaskID],并且在reduce阶段中,搭配nFiles变量,worker读取mr-0-TaskIDmr-1-TaskID....mr-nFiles-1-TaskID文件
    • nFiles:初始文件的数量,用于搭配TaskID,在上面已介绍
    • nReduce:用于map阶段,ihash(key) % nReduce
    type CallTaskArgs struct {
    }
    type CallTaskReply struct {
    	FileName string
    	TaskID   int
    	tp       taskType
    	nFiles   int
    	nReduce  int
    }
    
  3. 定义报告任务完成RPC的args和reply struct

    TaskID变量作用在CallTaskReply: TaskID 中提及

    tp的作用是用于coordinator判断该RPC是否是合法的,举例:worker-1成功请求到map-1任务,但是因为worker-1节点硬件问题处理缓慢而导致coordinator检测到该map-1任务超时,于是把map-1任务分配给了worker-2。等到某个时间点,已经完成所有map任务,coordinator进入到了reduce阶段,

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Go语言入门3(数组) 下一篇变量、常量

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目