Skip to content

🚀MIT6.5840分布式系统lab1-lab4,渐进式实现一个KV分布式系统,Golang实现。

License

Notifications You must be signed in to change notification settings

Yan0613/MIT6.824

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Jan 25, 2024
57b2d5a · Jan 25, 2024

History

66 Commits
Sep 17, 2023
Oct 23, 2023
Jan 25, 2024
Jan 25, 2024
Sep 17, 2023
Sep 17, 2023
Sep 17, 2023
Jan 25, 2024

Repository files navigation

MIT6.824

MIT6.824(现6.5840)分布式系统lab1-lab4,渐进式实现一个KV分布式系统

课程主页: https://pdos.csail.mit.edu/6.824/labs/lab-mr.html

Lab1 MapReduce

前置要求

Go语言基础(Lec2 go crawler demo:https://go.dev/tour/concurrency/1),重点掌握管道相关知识,MapReduce论文

MapReduce解析

Map是接收一组键值对,并且通过特定方式对其排序(在Lab1提到的word count例子中,键是词,值是词出现的次数,排序之后同一个词会集中出现)。 Reduce则合并相同键的值,以word count为例,Reduce是将相同单词的值(即出现的次数)相加。 Alt text

  • 系统会启动一个或多个Master,需要执行任务的机器启动Worker来处理任务。Master主要职责是分配任务给Worker,Master可以随机选择空闲的Worker来分配任务,或者Worker主动向Master请求任务;
  • 获得map任务的Worker,读取数据分片,生成一组key/value键值对的中间值集合,并将数据写到本地文件,这里每个map任务数据分为R份(Master创建reduce任务的数量),通过用户定义的分区函数(如hash(key) mod R)决定将key存在哪个文件;
  • 获得reduce任务的Worker,通过远程调用请求数据,数据加载完毕后,对数据进行排序,之后遍历数据,将相同key的数据进行合并,最终输出结果;
  • 当所有的map和reduce任务完成了,整个MapReduce程序就处理完毕了,Worker得到处理后的数据,通常会保存在不同的小文件中,合并这些文件之后就是最重要的结果。

实验过程

Alt text

  • Map阶段成功输出中间文件:
     {"Key":"Being","Value":"1"}
     {"Key":"it","Value":"1"}
     {"Key":"it","Value":"1"}
     {"Key":"it","Value":"1"}
     {"Key":"Being","Value":"1"}
     {"Key":"Being","Value":"1"}
     {"Key":"Merriman","Value":"1"}
     {"Key":"Cecily","Value":"1"}
     {"Key":"SCENES","Value":"1"}
     {"Key":"W","Value":"1"}
  • Reduce阶段成功输出mr-out-*
    Conan 3
    Concorde 1
    Confess 1
    Constantinople 4
    Contentment 1
    Contested 1

困难与思考

  1. map过程生成的中间文件到了reduce阶段没办法解码,发现是reduce阶段decoder应该直接解码到kv 最后一个crash test fail, 原因可能是在向maptaskfin管道发送完成信息的时候,worker还在向maptaskchan取任务,但是实际上此时管道内已经没有任务可以取出来了。
for {
    var kv []KeyValue
    if err := dec.Decode(&kv); err != nil {
        break
    }

    intermediate = append(intermediate, kv...)

}
  1. 为实现整个系统运行的稳定性,代码要实现检测worker超时相应的功能,超过10s未完成则重发任务,为此编写timetick函数,每隔一秒钟coordinator都要检查一次。一开始用chan存储task的开始时间和对应的task(出于线程安全的考虑),在遍历chan的时候却发现无法跳出遍历循环,因为go的channel是没有元素也会一直去取,而且更严重的问题是,每次取出一个task检查运行时间,如果未超时都要重新放进去,程序执行效率低下。因此改用数组存储,虽然目前没有发现线程安全引发的问题,但是仍然想尝试用一种更加优雅、最大保证线程安全的办法。

  2. 第二点里面提到检查用的是timetick函数,一秒钟检查一次,其实还可以用go的特性goroutine实现,并发执行不影响其他的进程。

Lab2 Raft

参考资料

Raft官网: https://raft.github.io/

图形化教程:http://thesecretlivesofdata.com/raft/

实验内容

  • 实现一个Raft算法 Raft是一个分布式一致性算法,用于在分布式系统中实现一致性状态机,保证分布式系统的一致性。 Alt text 文件目录结构及说明: persister.go , 一个简易版的持久化器,用于保存Raft协议状态和K/V服务器的快照。在 Raft 共识算法中,节点需要保存持久化状态,以便在发生故障或重启后能够恢复到先前的状态。 raft.go , Raft 共识算法的主要逻辑实现。 raft_test.go , 测试用例。 util.go , 一些工具函数。

Lab3

Alt text

About

🚀MIT6.5840分布式系统lab1-lab4,渐进式实现一个KV分布式系统,Golang实现。

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published