首页 > 其他分享 >Lab2B

Lab2B

时间:2023-01-11 22:01:27浏览次数:53  
标签:log cfg servers msg rf Lab2B leader

TODO

官方动画 https://raft.github.io/raftscope/index.html

  • 完成TestBasicAgree2B测试,实现Start()函数,编写AppendEntries代码实现log entry的发送和接收,通过applyCh发送和接收log entry.

  • 实现election restriction,论文的5.4.1章节.

  • 测试未达成协议的方法可以用重复选举,即使leader还正常工作.找到选举定时器或选举成功不发送心跳的bug.

  • 重复循环要加入sleep.

  • 帮未来的自己一个忙,保持代码整洁.

  • 如果测试失败了,看一下config和test的代码,了解测试流程.

测试案例

TestBasicAgree2B

  1. 调用start前不应该有peer接收到log
  2. 遍历所有peers,如果有leader,调用start函数
  3. 如果调用成功,测试是否所有peer收到正确log

记得提交log同时通过applych发送log

img

TestRPCBytes2B

校验RPC发送的字节数,确保每个log只对peer发送一次,发送10条log,校验log command字节总数与抓包捕获的字节总数是否一致.

img

For2023TestFollowerFailure2B

校验Follow丢失连接之后是否正常工作

img

For2023TestLeaderFailure2B

校验Leader丢失连接之后是否正常工作

  1. 发送一条log
  2. 断开leader连接,剩下两个peer选出一个leader,再发送两条log
  3. 断开leader连接,现在客户端只能连接一个peer
  4. 遍历peer调用start() 测试是否有peer提交了日志

之前leader向follow同步日志成功修改matchindex时加上同步日志的数量,在leader重新选举后matchindex列表会初始化为0,需要改为nextindex - 1

rf.nextIndex[server] += len(args.Entries)
rf.matchIndex[server] += len(args.Entries)

rf.matchIndex[server] = rf.nextIndex[server] - 1

img

TestFailAgree2B

校验follow断开连接后发送4条log,之后重连,再发送两条日志,是否正常工作

func TestFailAgree2B(t *testing.T) {
	servers := 3
	cfg := make_config(t, servers, false, false)
	defer cfg.cleanup()

	cfg.begin("Test (2B): agreement after follower reconnects")

	cfg.one(101, servers, false)
    // client发送msg:101,leader:S1收到并同步到S0 S2  
	leader := cfg.checkOneLeader()
	cfg.disconnect((leader + 1) % servers)

	cfg.one(102, servers-1, false)
	cfg.one(103, servers-1, false)
	time.Sleep(RaftElectionTimeout)
    // 此时disconnect 的 follow会timeout并开始选举 但是拿不到选票只会自增term 为2
	cfg.one(104, servers-1, false)
	cfg.one(105, servers-1, false)
    // leader接收到 102 103 104 105 并同步到正常的follow

	// 恢复连接 此时leader发送的appendrpc的reply term会大于leader term 把自己置为follow 超时开始选举
	PrettyDebug(dTrace, "S%d re connect TestFailAgree2B ", (leader+1)%servers)
	cfg.connect((leader + 1) % servers)

	// the full set of servers should preserve
	// previous agreements, and be able to agree
	// on new commands.
	cfg.one(106, servers, true)
    // 选举成功此时term=3,但是106提交的日志是term2提交的,所以106日志不会提交到状态机
	time.Sleep(RaftElectionTimeout)
	cfg.one(107, servers, true)

	cfg.end()
}

还有个问题是106log到来的时候是term1写入的,然后重新选举到了term3,这时候由于106log的term与current term不一致,所以不会提交

	// 原来更新commitindex是从小到大更新,要改为从最新的index从大到小更新
    N := rf.commitIndex + 1
	count := 1
	for server := range rf.peers {
		if server == rf.me {
			continue
		}
		if rf.matchIndex[server] >= N {
			count++
		}
		if count > len(rf.peers)/2 {
			PrettyDebug(dLog, "S%d,updateCommitIndex server:%d,count:%d,rf.log[N].Term:%d,rf.currentTerm:%d",
				rf.me, server, count, rf.log[N].Term, rf.currentTerm)
		}

		if count > len(rf.peers)/2 && int64(rf.log[N].Term) == rf.currentTerm {
			PrettyDebug(dLog, "S%d,updateCommitIndex rf.commitIndex++",
				rf.me, rf.commitIndex)
			rf.commitIndex++
			break
		}
	}

img

TestFailNoAgree2B

5个peers,断连3个后重连,测试是否正常

TERM 1: 5个peer都写入 msg 10

S2 S3 S4 断线 超时

S1 写入 msg 20 index 2

转TERM 2 开始选举 恢复连接

S3 成为 TERM 3的 leader

写入msg 30 msg 1000

这时候S1的log index=2 为msg20,prelog 1 的index和term都匹配,直接把msg 30 1000插入了,应该要把msg20删除的

img

TestConcurrentStarts2B

处理并发Start()写入

img

TestRejoin2B

  1. 写入msg 101 leader1断开连接
  2. leader1写入102 103 104
  3. leader2写入103 然后断开连接
  4. leader1重连
  5. 请求写入104
  6. leader2重连
  7. 写入105

img

当server 0 重新上线之后与仅存的一个peer日志不同,永远选不出leader来,这里是被翻译版的fig2坑了,后来查原文说的是 at least as up-to-date,至少不晚于

img

img

修改逻辑为:

  • 如果 term 不同,那 term 新的那个 log 胜出;
  • 如果 term 相同,那 index 更大(即更长)的那个 log 胜出。

img

img

在第6步leader2重连之后会同时存在两个leader,当leader1发送logapppend给leader2,leader2同时发送logapppend给leader1,leader2发送之前要解锁,这一瞬间收到了leader1的log,发现term比自己大,转为follow,并且同步log,这时候sendappendlog的rpc args就会data race,这一步卡了很久.后来发现是appendargs构建日志的时候要深拷贝.

img

TestBackup2B

在少部分节点失效,多部分节点失效环境下,尽快完成两百个命令的正确处理.

随机提交msg,然后3个follow 2 3 4断开,向leader1 2提交50个msg,然后剩下两个节点也断开,2 3 4重连,向新集群
提交50个msg,断开现在的一个follow,给现在的leader发送50个msg,断开所有节点,重连3个节点,提交50个msg,重连所有节点,然后提交1个msg,不能出错

img
当全部节点丢失链接然后1 3 4节点连接后,3号和4号节点一直自增竞选,1号节点接收到投票请求后重置了选举时间,所以一直不发起选举,而3 4节点的日志落后一直拿不到1号节点的选票.

TestCount2B

检查无效通信的次数,这个没有出问题

标签:log,cfg,servers,msg,rf,Lab2B,leader
From: https://www.cnblogs.com/autumnnnn/p/17045015.html

相关文章