mit6.824-lab2b日志一致性

主要内容:client调用start()添加日志后,raft如何保证日志如何被安全、可靠、快速的添加到raft集群中。

Start函数

客户端调用Start函数后应立即返回,无论raft添加结果如何。如果当前节点是leader的话,则更新自己的日志。

//客户端发送command消息
func (rf *Raft) Start(command interface{}) (int, int, bool) 
...
//leader: 更新日志
		log := Log{term, command, index}
		rf.entries = append(rf.entries, log)
		rf.matchIndex[rf.me] = len(rf.entries) - 1
		rf.cond.Signal() //通知发送更改包(心跳)

AppendEntries函数

leader通过调用AppendEntries rpc来更新follower的日志。

leader由nextIndex[i]可以知道要发送给该服务器的下一条日志索引,并将前一条日志的索引(prevLogIndex)、任期(prevLogTerm)、Entries[nextIndex[i]:]作为参数发送给follower,follower凭借上列参数更新自己的日志。
接收者(follower)具体流程

  1. 检测leader合法性
  2. 重置选举计时器
  3. 检测日志中是否包含与leader一致的Entries[prevLogIndex]
  4. 根据参数Entries更新自己的日志。
  5. 更新commitIndex

过程很简单,可是raft论文中有很多隐晦的地方没有讲清楚,算是有不少坑在这里。

快重传:在前三步的检测失败时,告知leader失败的原因,并且告知leader下一次发送的nextIndex[i]。
在reply中加入三个变量:Xterm(冲突的任期)、Xlen(日志空位)、Xindex(下次发送的index)。

如果follower存在prevLogIndex的日志,并且发生冲突的话,返回follower冲突日志所对应任期的第一条日志Index。
https://mit-public-courses-cn-translatio.gitbook.io/mit6-824/lecture-07-raft2/7.3-hui-fu-jia-su-backup-acceleration

第四步中,需要注意:添加follower中没有的日志,需要处理已经包含、冲突、缺少的问题
如果leader的nextIndex=[2,2,2],follower的日志在更新完后必须为1234。

server当前日志接收的日志
leader1234
follower1123[3,4]
follower21256[3,4]
follower312[3,4]

整体架构&goroutine

	go rf.ticker()
	go rf.UpdateOtherLogsLoop()
	go rf.applier()
	go rf.UpdateOtherLogSignal()

ticker:lab2a选举相关
UpdateOtherLogs*:发送心跳包,发送心跳的时候顺带更新日志
applier:周期检查日志是否被提交,如果已经提交,则应用到状态机,<-Applych

发送心跳包用了两个goroutine:Loop和Signal。
Loop为周期性发送心跳,每隔100ms发送一次。
Signal为响应式发送心跳,包阻塞在sync.cond上,每当Client调用Start()时,leader成功添加command到自己的日志,就会调用cond.signal(),立即发送更新日志的请求。
如果只用Loop发送心跳包,运行lab2b:90s+,Loop+Signal:60s+。

修改:在goroutine中,SendAppendEntries更新成功后,立马进行commitIndex更新操作。

lab2b 50s+
在这里插入图片描述

分布式技巧:

当存在以下形式时:

for{ 
	go fun(){
	}()
} 
...go func()执行结果进行操作..

修改成下列形式:

for{ 
	go fun(){
		...
	    ...go func()执行结果进行操作...
	}()
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值