这是 MIT 6.824 课程 lab1 的学习总结,记录我在学习过程中的收获和踩的坑。
我的实验环境是 windows 10,所以对lab的code 做了一些环境上的修改,如果你仅仅对code 感兴趣,请移步 : github/zouzhitao
mapreduce overview
先大致看一下 mapreduce 到底是什么
我个人的简单理解是这样的: mapreduce 就是一种分布式处理用户特定任务的系统。它大概是这样处理的。
用户提供两个函数
mapFunc(k1,v1)-> list(k2,v2)
reduceFunc(k2,list(v2)) -> ans of k2
这个 分布式系统 将用户的任务做分布式处理,最终为每一个 k2
生成答案。下面我们就来描述一下,这个分布式系统是如何处理的。
首先,他有一个 master
来做任务调度。
master
- 先调度 worker 做 map 任务,设总的 map 任务的数目为 M M M , 将result 存储在 中间文件 m-i-j 中, i ∈ { 0 , … , M − 1 } , j ∈ 0 , … , R − 1 i \in \{0,\dots ,M-1\}, j \in {0,\dots,R-1} i∈{ 0,…,M−1},j∈0,…,R−1
- 调度 worker 做 reduce 任务,设总的 reduce 任务数目为 R R R, 将答案储存在 r j r_j rj
- 然后将所有的renduce 任务的ans merge起来作为答案放在一个文件中交给用户。
detail 都在实验中
detail
这部分讲 实验内容(观看code), 不过不按照 lab 顺序将。个人认为 做lab的目的,不是做lab 而是为了搞懂 mapreduce system
master
我们先来看看 master 这部分的代码
// Master holds all the state that the master needs to keep track of.
type Master struct {
sync.Mutex
address string
doneChannel chan bool
// protected by the mutex
newCond *sync.Cond // signals when Register() adds to workers[]
workers []string // each worker's UNIX-domain socket name -- its RPC address
// Per-task information
jobName string // Name of currently executing job
files []string // Input files
nReduce int // Number of reduce partitions
shutdown chan struct{
}
l net.Listener
stats []int
}
master 维护了执行一个 job 需要的所有状态
master.run
这部分是 master 具体做的事情
// Distributed schedules map and reduce tasks on workers that register with the
// master over RPC.
func Distributed(jobName string, files []string, nreduce int, master string) (mr *Master) {
mr = newMaster(master)
mr.startRPCServer()
go mr.run(jobName, files, nreduce,
func(phase jobPhase) {
ch := make(chan string) // worker 的地址
go mr.forwardRegistrations(ch)
schedule(mr.jobName, mr.files, mr.nReduce, phase, ch)
},
func() {
mr.stats = mr.killWorkers()
mr.stopRPCServer()
})
return
}
// run executes a mapreduce job on the given number of mappers and reducers.
//
// First, it divides up the input file among the given number of mappers, and
// schedules each task on workers as they become available. Each map task bins
// its output in a number of bins equal to the given number of reduce tasks.
// Once all the mappers have finished, workers are assigned re