6.824 Lab

6.824 Lab: details and debug

6.824实验的一些记录

List

Map-Reduce

        Worker 						Coordinator
        ----> 	AskForTask 			---->
        <---- 	assign Map task 	<----
        ----> 	ReduceMap	     	---->
        <----	Check Can Write		<----
CanWrite----> 	FinishMap			---->
either	----> 	abort

        ----> 	AskForTask		 	---->
        <---- 	assign Reduce task 	<----
        ----> 	ReduceWrite	     	---->
        <----	Check Can Write		<----
CanWrite---->	FinishReduce		---->
either	---->	abort

And c.CheckFail() check whether running workers delay or crash To protect from data racing, use lock (chan int) to protect map

采用两阶段协议完成,Coordinator为每个过程完成一个RPC Handler即可 Worker采用一个循环,向Coordinator请求任务

Raft

必看内容

raft.pdf

Guidance

students-guide-to-raft(内容和许多实现细节有关)

2A Leader Election

Ticker()循环作为Leader发送heartbeats或者Follower变为Candidate开始新一轮的选举。

重置选举计时器的时间,见students-guide-to-raft

2B Log Replication

循环中不应该有会阻塞的地方,有阻塞如rpc call等应该全部使用go routine去单独运行

applier循环检查commitIndex和lastApplied,应用

在每次收到成功的appendEntry后,leader进行commitIndex的调整

AppendEntry处理heartbeats和一般的AppendEntry是一样的。正常情况下,follower的matchIndex和nextIndex紧跟Leader的log,entries的长度为0,当落后时,Entries才会有内容,同时,对Heartbeat的处理AppendEntries RPC的5条规则都应实现,所以不做区分。

使用函数粒度的锁

调用rpc需要释放锁,因为一个rpc可能很久才会返回。返回后,进行操作仍然需要检查当前server的state仍未调用rpc前的角色(主要指Leader)。

log打印,使用go自带的log,util.go文件和log相关,按照一定的格式打印,可以使用脚本进行可视化

fast roll back优化

Leader使用rpc调用appendEntry时,返回值应使用args中的值进行更新

2C Persist

直接把persist加进去即可

2D Snapshot

这里重构了,将election, commit, apply都用了一个ticker

完成三个函数后,需要注意到要在apply之前install snapshot,不能用异步,即需要安装snapshot时,不能apply。

测试的注意事项:-race选项非常耗内存(1T约400M),多线程测试需要谨慎选择线程数量

同时测试线程数过多可能会导致一些看起来log突然截至,系统继续运行,channel阻塞等问题,测试结果一个有完全性能的核心可进行10个并行的测试。(阿里云不超过突发实例性能20%(2c2G)可以同时5次测试)