首页 > 其他 > 详细

Raft详解分析

时间:2016-09-27 19:19:22      阅读:181      评论:0      收藏:0      [点我收藏+]

1、投票部分

一个candidate向所有其他的server发送RequesetVote RPC(具体格式见论文),每次从RPC的reply中累加voteCount,如果超过一半,这个candidate变成leader,把这个消息放到channel中,反之选举失败,变成follower对应go 代码为:

if ok { //获取投票结果
if reply.VOTEGRANTED {
rf.mu.Lock()
rf.voteCount = rf.voteCount + 1
// println("rf.me: " + strconv.Itoa(rf.me) + " voteFrom: " + strconv.Itoa(server) + " voteCount: " + strconv.Itoa(rf.voteCount))
rf.mu.Unlock()
if rf.state == "candidate" && rf.voteCount > len(rf.peers)/2 {
rf.BecomeLeaderCH <- true
}
} else if reply.TERM > rf.CurrentTerm {
rf.mu.Lock()
rf.CurrentTerm = reply.TERM
rf.state = "follower"
rf.mu.Unlock()
// println(strconv.Itoa(server) + " reject " + strconv.Itoa(rf.me) + " and " + strconv.Itoa(rf.me) + " step down as follower")

如何处理放到channel中的选举结果呢?首先从channel中取出结果,如果是leader表示自己当选,修改自己状态为leader,把每个follower的nextIndex设置为当前leader的最后一个log的index(参见Raft论文),发送AppendEntries heartbeat 如果选举失败,则变成follower

func (rf *Raft) CandidateState() {
.......
select { 
case <-rf.heartbeatCH://已经有人当上leader,选举失败
println("no longer panic, back to follower")
rf.state = "follower"
return
case becomeLeader := <-rf.BecomeLeaderCH: //选举成功
if becomeLeader { 
rf.state = "leader"
rf.mu.Lock()
rf.NextIndex = []int{}
for i:=0; i < len(rf.peers); i++ {
rf.nextIndex = append(rf.nextIndex, len(rf.logs)-1) //把每个server 的nextIndex设置为最后一个元素
}
rf.mu.Unlock()
go rf.BroadcastAppendEntriesRPC()
return
}

default:
return  //多个竞争,大家都没有当上leader,则返回,在外部循环中重新设置各个candidate定时器,再次选举
}
}

Raft详解分析

原文:http://www.cnblogs.com/yanchengwang/p/5913714.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!