MIT 6.824 Lab 1学习笔记
Lab 1
理论部分
节选摘抄
- MapReduce出现的契机
在过去的五年时间里,包括作者在内的许多谷歌工作人员实现了数以百计的、用于特殊目的的计算程序来处理大量的原始数据,例如爬虫获取到的文档、网络请求日志等等。
其目的是为了计算出各种类型的衍生数据,例如倒排索引、多种关于web文档的图结构表示、被每个主机所爬取的页面数摘要、给定的某天中被最频繁查询的集合等等。
大多数这样的计算在概念上都很简单,然而输入的数据却通常是巨大的。而且为了能在一个合理的时间范围内完成,计算操作需要被分配到数百甚至数千台机器上运行。
关于如何并行计算,如何分派数据以及如何处理故障等问题被混杂在了一起,使得原本简单的计算逻辑被用于处理这些问题的大量复杂代码所模糊为了应对这些复杂性,我们设计了一个全新的抽象,该抽象允许我们表达我们想要执行的简单计算,但是将关于并行化、容错、数据分发和负载均衡等机制中复杂、繁琐的细节隐藏在了库中
- 技术模型
这一计算获得并输入一个k/v键值对集合,然后生成并输出一个k/v键值对集合。
MapReduce库的用户通过Map和Reduce这两个函数来表达该计算逻辑。Map函数是由用户编写的,其获得一个输入的k/v对并生成一个中间态的k/v对
MapReduce库对所有的k/v对进行分组,使得所有有着相同中间态key值的k/v对的value值组合在一起,然后将它们传递给Reduce函数。Reduce函数也是由用户编写的,其接收一个中间态的key值和与该键对应的一组value值的集合。
它会将这些value值进行统一的合并以形成一个可能更小的value值集合。
通常,每次reduce调用只会生成零个或一个输出值。这个中间态的value集合通过一个迭代器提供给用户的reduce函数。
这允许我们得以处理那些无法被完整放入内存的,过大的列表集合。
架构图
摘抄自论文
实践部分
准备工作
克隆代码仓库
$ git clone git://g.csail.mit.edu/6.5840-golabs-2026 6.5840
$ cd 6.5840检查已实现的源代码能否运行
检查单词计数器
原版指令是给Unix Go编译器用的:
$ cd ~/6.5840
$ cd src/main
$ go build -buildmode=plugin ../mrapps/wc.go直接运行会得到:
F:\GolandProjects\6.5840\src\main>go build -buildmode=plugin ../mrapps/wc.go
-buildmode=plugin not supported on windows/amd64我把wc.go迁移到了src/main/plugins/official/mr下,并修改源代码中的package,以及mrsequal.go代码中的CLI用法示例和判定条件,改为利用go package导包(要切换包的话就自己改目录路径)
然后是通配符语法,pg*.txt的通配符语法在Windows环境不起效,好在filepath库提供了GlobAPI,所以:
for _, filename := range os.Args[1:] {
matches, err := filepath.Glob(filename)
if err != nil {
log.Printf("模糊搜索%v文件时发生异常: %v", filename, err)
continue
}
if len(matches) == 0 {
log.Printf("未找到%v文件", filename)
continue
}
for _, matched := range matches {
content, err := os.ReadFile(matched)
if err != nil {
log.Printf("读取文件%v时发生异常: %v", matched, err)
continue
}
kva := mapf(filename, string(content))
intermediate = append(intermediate, kva...)
}
}然后:
# src/main
go run mrsequal.go pg*.txt
rm mr-out-*测试样例也是,要么重写要么上Unix
实现模块
注意
合并分支时出现了索引污染,我果断删除git仓库,但是忘记物理备份源代码,所以源代码全部都没了
RPC传参结构体
Coordinator
Worker
最终成果

左边是随机崩溃测试后的sort输出, 右边是单worker测试后的sort输出

左边是mrsequal.go输出,右边是随机崩溃测试后的sort输出
会多出一些单词,不过总体顺序是对的
Lab 2:实现KV系统的服务与客户端
理论部分
实践部分
花絮
在缓存路径里找EXE的幽默测试样例


- 猜测是因为
kvsrv1d不带后缀名,Windows上构建的Go程序默认会到缓存路径里找文件,即便用的是带路径分隔符的绝对路径 - 给
prod打个补丁,检查runtime.GOOS,看情况补个.exe后缀就解决了
疑似Pure Go 网络栈


不过底层还是unix文件套接字,还是起Linux虚拟机