zoukankan      html  css  js  c++  java
  • Raft详解分析

    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定时器,再次选举
    }
    }

  • 相关阅读:
    创建局域网方案!!!!!--安全的物联网技术方案使用说明与管理
    创建局域网方案!!!!!--交叉编译步骤和使用事项!!
    java学习与应用(1)--基本回顾
    iptables的nat使用记事
    iptables交叉编译记事
    telnet传输文件
    tensorflow零起点快速入门(6) --np与tf
    Sinlinx交叉编译半途记事
    tensorflow零起点快速入门(5) --强化学习摘录截图(tf与np)
    Latex使用记事(1)
  • 原文地址:https://www.cnblogs.com/yanchengwang/p/5913714.html
Copyright © 2011-2022 走看看