mit6.824-lab3A

本文档介绍了如何实现一个基于Raft一致性算法的KV服务器,包括客户端和服务器端的设计,以及针对不同测试场景的调试过程。实验中强调了命令的序列号去重、并发控制和状态机的正确应用,同时指出了在测试过程中遇到的问题和解决方案。
摘要由CSDN通过智能技术生成

实验简介

实现基于raft的KV服务器,您将需要修改kvraft / client.gokvraft / server.go,甚至可能是kvraft / common.go

一定要保证lab2是正确的,不然这个实验到处是问题。

实验参考:

  • https://www.cnblogs.com/mignet/p/6824_Lab_3_KVRaft_3A.html
  • https://blog.csdn.net/Miracle_ma/article/details/80184594

Client

通过RPC调用server的服务,需要考虑两个问题?

  1. 如果call超时,那么client就会超时重发。如果是因为网络延迟,那么server就会收到两次命令,确保服务端只执行一次命令(多次append会导致逻辑错误)。使用类似TCP的序列号,来去重。
  2. client应记录raft的Leader,就不用每次循环去尝试

PutAppend和Get的逻辑是完全一样的

Server

server不能立即执行client的命令,而是把命令反应给raft服务,等raft状态机提交了该命令后,再执行。

Part 3A

TestBasic3A

写了个最简单的版本

func (kv *KVServer) PutAppend(args *PutAppendArgs, reply *PutAppendReply) {
   
	// Your code here.
	cmd := Op{
   
		Key:   args.Key,
		Value: args.Value,
		Option:    args.Op,
	}
	reply.WrongLeader = false
	_, _, isLeader := kv.rf.Start(cmd)
	if isLeader == false {
   
		reply.WrongLeader = true
		return
	}
	// TODO : 这样做的话,每次只能处理一个请求
	kv.mu.Lock()
	defer kv.mu.Unlock()
	select {
   
	case cmd := <- kv.applyCh:
		op := cmd.Command.(Op)
		kv.doCmd(&op)
	case <- time.After(500 * time.Millisecond):
		reply.Err = ErrTimeOut
		return
	}
	LogDebug("C%d-%d %s key%s success, req=%d", args.ClientId, args.RequestId, args.Op, args.Key)
}

有时会通不过,raft日志如下:

10:49:16.407109 	Start():{
   0 x 0 111 y Append 4 249}
10:49:16.482170 {
   true {
   0 x 0 111 y Append 4 249} 397}
10:49:16.482984 	Start():{
   0 x 0 112 y Append 4 250}
1
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值