MIT6.824-Lab1-P3

Part III: Distributing MapReduce tasks

要干什么?

前面的都是串行执行MRTask, 这次我们要用多线程模拟分布式环境, 来进行分布式MR.
具体的任务是: 完善schedule.go: schedule():

  1. 从registerChan读取已注册worker, 它会返回一个包含worker的rpc地址的字符串.
  2. 给每一个worker分配一系列任务
  3. 等待所有Task完成后, 返回
  4. schedule()应该使用全部worker, 有一些worker可能在schedule() 执行时才启动.
  5. schedul()通过Worker.DoTask()让worker执行任务.

前置条件

因为设计到并发编程, 所以我们可能要用到:

  • goroutine
  • channel
  • go的RPC库, 用来和Worker通信
  • sync.WaitGroup
  • Go的race detector.
  • select语句, 用来检查超时

我们还要了解如下文件:

  • mapreduce/common_rpc.go
  • mapreduce/master.go
  • mapreduce/worker.go

如何调度

为每个worker一次性分配若干个task

这是作者最初的思路。

为每个task分配一个worker

这是后面采用的思路,参考了这篇博客
具体来说,就是每一个task都开启一个单独的线程,然后每次给一个worker分配一个task,每次worker完成task后, 将worker放入registerChan,这样worker可以等待分配下一个task.

潜在问题

笔者采用了为每个task分配一个worker。但是这里有一个坑, register是同步channel, 也就是如果A做完了任务n-2, 把A放入register之后,B做完了任务n-1,此时没有任务可执行了,那么没有线程从register里面取出A, 此时也无法把B放入register。

这就是sync chan导致的死锁,有两种解决方法:1)把register <- Name放入一个goroutine中,这个goroutine会被阻塞但当其父线程结束时也会一起结束。2)加个条件判断,最后一个任务完成后不要把Name放进去。

阅读 305

推荐阅读
从菜鸡到菜须鲲
用户专栏

1 人关注
11 篇文章
专栏主页