mit_6.824_2021_lab3A
mit_6.824_2021_lab3A_kvraft
lab3 系列是将此前写好的 lab2 的 raft 库加以调用,在此基础之上实现上层的状态机,即 service 层;所以,lab2 写得不好,lab3 怎么也过不去,故需要确保 lab2 基本万无一失;
但是在此基础上,还需要依靠 service 层实现线性一致性,lab3 工作量不大,但是还是需要有良好的设计
参考了网上的部分博客和思路
https://blog.csdn.net/qq_40443651/article/details/117172246
https://www.codercto.com/a/84326.html
lab3A_Key/value_service_without_snapshots
实验内容
-
使用 lab2的 raft 库构建一个 kv 服务端,是一个复制状态机,以及一个客户端 Clerk
-
kv服务支持三种操作:Put, Append, Get。通过在内存维护一个简单的键/值对数据库,键和值都是字符串;
对于不存在的键的Get应该返回一个空字符串。对不存在的键的 Append 应该类似于Put
-
符合强一致性,即线性一致性
实验提示
客户端有时会不知道谁是 leader。lab3 的要求仅需要换个 server,重试即可;如果操作未能提交(例如,如果leader被替换了),服务器就会报告一个错误,然后Clerk会使用另一个服务器重试。
你的kvservers不应该直接通信,它们只能通过Raft进行互动。这句要求,在构建上层 service 就有体会,共识协议让分布式系统对外表现得像一个副本一样。
定义 Op
Op 是上层 service 和 raft 之间交互的语义日志, 通过 Start()
API 向Raft日志中输入一个Op,需要使用 Op 描述Put/Append/Get操作;
每个服务器都应该在Raft提交Op命令时执行它们,即当它们出现在applyCh
时。
当Raft提交它的Op时,leader 与 follower 不同之处在于,需要通知 RPC处理程序并作出响应。
-
小心 kvserver和它的Raft库之间的死锁
-
可以添加 Raft ApplyMsg 或rpc(如AppendEntries)的字段,但这应该不是必需的
-
如果kvserver 发生网络分区并为少数派,那么 leader 就不应该响应 RPC请求 (以便它不服务过时的数据)。
一个简单的解决方案是在Raft日志中输入每个 Rpc 操作,如