6.5840 Lab 1: MapReduce
对于Lab1 MapReduce的思路总结
实验1 我们有三个部分需要实现 worker coordinator MapReduce rpc。 讲解一下具体的思路:
- 实验的执行环境使用WSL2 + git + vscode
- 需要理解什么是RPC
- Map 和 Reduce的功能
- 调度器怎么工作?
- Worker如何寻找任务
首先我们需要在脑子里面构建出项目运行的真实场景是什么样的?我们才能设计相应的结构体。
对于Go本身远程过程调用 使用 net/rpc :
net/rpc 包是一个轻量级 RPC(远程过程调用)框架,看起来像本地调用,其实底层通过 TCP/HTTP 序列化参数、发送、解码、执行。
在实验中 实验为我们搭建了远程过程调用我们只需要按照框架 编写相应的函数!然后直接调用,因为我做的是在一台机器上 实际上我们启动了两个进程我们通过进程进行通信, 具体体现是c, err := rpc.DialHTTP("unix", sockname) 因为在同一台机器我们使用了 Unix域套接字的RPC客户端连接
使用HTTP作为RPC的传输协议,但运行在Unix域套接字上,不是真正的网络HTTP
TOLEARN: Unix域套接字 **TOLEARN: ** RPC
调度器的实现思路
首先 Worker 会不断向 Coordinator 请求任务, Coordinator 需要监听Worker的请求并返回响应 , 而 Coordinator 需要初始化任务 MAP REDUCE 等待 Worker 取走他们 Worker怎么取? 从哪里取? 也就是通过 RPC 我们需要将 Coordinator 的函数注册到RPC中 这里的函数注册也需要理解一下, 我们需要将函数注册为RPC方法 必须满足的条件: 正确的参数 正确的函数名 正确的返回值 这样注册之后 Worker 传来的请求就会被正确的打入到 Coordinator 的方法中 反之也是一样!
Coordinator 在 Worker 打入请求之后 Coordinator 需要遍历 MAP 任务寻找空闲的任务(任务的状态管理),我们需要在 Coordinator 中时刻保持正确的状态改变! 因为 Coordinator 才是最终管理任务的状态! MAP 的核心任务在做什么? 交给 Worker 我们在下面说 然后同理遍历空闲的 Reduce 任务 Reduce 是由我们决定的 他的数量是有我们初始化的 而Map的数量是由我们的输入多少个文件决定的, Reduce 就好像提前为我们规划出几个空间 Map 任务执行任务后的输出会被分配到 固定的 Reduce 中然后整合结果
处理 Worker 传进的任务完成信号 在这里我们需要改变任务的状态,正确的更改任务的状态 我们才能正确的分配任务
中间遇到了很多问题 通过 fmt.Println() 来找找代码到底在哪里出现了问题!
工作者的实现思路
Worker 是真正处理 MAP和 REDUCE的工作者, 我们可以开启多个 Worker 也就是多个进程 在分布式中就是多个机器 Worker 处理从终端中获取需要处理的文件, 对于文件的操作: 打开文件 读取文件内容 交给实验给我们实现的 mapf() 函数 我们需要知道mapf 函数输出的结果是什么?对结果进行处理 是一个KeyValue类型的切片 我们将mapf产生的中间文件存储到正确的位置中, 我们通过将mapf的输出结果通过 hash 进行分组 等待Reduce 处理 然后reduce任务的处理
Json包: 根据 reduce 数量进行分区 然后通过hash(key)之后 将 key value 序列化放进入到相应的 reduce 任务中 这个文件的名称我们必须让双方按照同样的约定写入和读取!按照事先约定的格式 打开文件 此时 map 已经写入了文件! 然后对数据进行JSON反序列化提取 根据Key进行排序整合!(设计一点小算法很简单 但是我没有想出来)!
然后 Worker 告诉 Coordinator 完成任务 Coordinator 进行真正的任务状态改变!
容错机制: 这里我实现的并不好 但是大体的思路是: Coordinator 定期检查 任务的状态 如果任务超时那么我们将任务的状态更新等待重新 Worker 申请并分配