MIT 6.824 分布式系统课程lab实现 (2) lab1 MapReduce

Master数据结构定义

type Master struct {
    // Your definitions here.
    //Master进程会被并发访问,需要使用Lock用于保护共享资源的访问
    Lock        sync.Mutex
    MasterState int
    //使用队列存储尚待发布的任务
    MapTaskQueue              *list.List
    //任务超时后使用MapTaskId获取MapTask详情
    MapTaskBuffer             []MapTask
    //每个MapTask对应的SessionId,当Worker传递的SessionId与记录不同的话,说明是失效数据丢弃
    SessionIdOfMapTask        []int

    CurrentSessionIdOfMapTask int
    //记录完成的MapTask数量,当达到要求时,进入下一阶段
    FinishedMapTaskCount      int
    //用于接收任务完成信号的channel数组
    MapTimerChannels          []chan int
    

    //Reduce任务相关变量, 同上
    ReduceTaskQueue              *list.List
    ReduceTaskBuffer             []ReduceTask
    SessionIdOfReduceTask        []int
    CurrentSessionIdofReduceTask int
    FinishedReduceTaskCount      int
    ReduceTimerChannels          []chan int
}

Master与Workers之间的通信方式

  1. 所有通信(RPC)都由Worker主动发起
  2. 一共有两种RPC

    1. Worker向Master发送请求CallAssignTask()
    2. Worker完成任务后调用CallConfirmTask()通知Master,让Master检测Worker工作是否合法
  3. Master和Worker之间的通信是无状态的,Master仅保存分配的Task对应的SessionId.
  4. Worker在完成工作后调用CallConfirmTask()通知Master,Master检查传入的SessionId与CurrentSessionIdofTask中存储的是否合法

通信使用的数据结构

type WorkerMessage struct {
    SessionId     int
    TaskType      int
    TheMapTask    MapTask
    TheReduceTask ReduceTask
}

type MasterMessage struct {
    MasterMessageType int
    SessionId         int
    TaskType          int
    TheMapTask        MapTask
    TheReduceTask     ReduceTask
}

超时处理

func (m *Master) StartMapTiming(MapTaskId int) {
    select {
    case <-m.MapTimerChannels[MapTaskId]:
    //根据超时信号与完成信号哪一个先到达,执行哪一个步骤
    //当超时时重新入队
    case <-time.After(TimeoutUpperLimit):
        m.Lock.Lock()
        defer m.Lock.Unlock()
        fmt.Printf("\n%v timeout\n", MapTaskId)
        mapTask := m.MapTaskBuffer[MapTaskId]
        m.SessionIdOfMapTask[MapTaskId] = -1
        m.MapTaskQueue.PushBack(mapTask)
    }
}

Worker处理文件

  1. 这里使用课程提供的hints,使用json包进行编码
  2. Worker在调用CallAssignTask()请求任务之后读取文件并调用mapf, reducef函数处理后写入到tempFile,完成之后调用CallConfirmTask()通知Master,Master根据SessionId是否合法通知Worker, Worker再根据Master的通知删除tempFile或者修改tempFile文件名为合法的文件名.

你可能感兴趣的:(分布式系统golang)