raft 算法實現(xiàn)

//1.實現(xiàn)3節(jié)點選舉
//2.改造代碼成分布式選舉代碼,加入Rpc調(diào)用
//3.演示完整代碼 自動選主  日志復制


//定義3節(jié)點常量
const raftCount =3

/**
    Leader對象
    Term int             任期 還沒上任為0
    LeaderId int         leaderId 編號 沒有編號為-1
 */
type Leader struct {
    Term int
    LeaderId int
}

/**raft的聲明

鎖                                                     mu                             sync.Mutex
節(jié)點編號                                               me                              int
當前任期                                               currentTerm               int
為哪個節(jié)點投票 -1代表誰都不投             vatedFor                     int
0.follower 1.candidate 2.leader  state                        int
發(fā)送最后一條消息的時間                         lastMessaheTime           int64
當前節(jié)點的leader                               currentLeader             int
節(jié)點間發(fā)送信息的通道                            message                        chan bool
選舉通道                                              electCh                        chan bool
心跳信號的通道                                    heartBeat                    chan bool
返回心跳信號的通道                                 heartbeatRe                  chan bool
超時時間                                              timeout                        int
 */
type Raft struct{
    mu              sync.Mutex
    me              int
    currentTerm     int
    votedFor        int
    state           int
    lastMessaheTime int64
    currentLeader   int
    message         chan bool
    electCh         chan bool
    heartBeat       chan bool
    heartbeatRe     chan bool
    timeout         int
}

var leader = Leader{0,-1}
func main() {
    //過程:有三個節(jié)點,最初都是follower
    //如果有candidate狀態(tài),進行投票和拉票
    //會產(chǎn)生leader
    //會產(chǎn)生3個節(jié)點
    for i:=0;i<raftCount;i++{
        //穿件三個raft節(jié)點
        Make(i)
    }

}

func Make(me int ) *Raft  {
    rf:=&Raft{}
    rf.me=me
    rf.votedFor=-1
    rf.state=0
    rf.timeout=0
    rf.currentLeader=-1
    rf.setTerm(0)
    rf.message=make(chan bool)
    rf.electCh=make(chan bool)
    rf.heartBeat=make(chan bool)
    rf.heartbeatRe=make(chan bool)
    //設置隨機種子
    rand.Seed(time.Now().UnixNano())
    //選舉協(xié)程
     go rf.election()
    //心跳檢測協(xié)程
    go rf.sendLeaderHeartBeat()
    return rf
}
/** setTerm for currentTerm
    for Raft struct
    params term int which one item number
 */
func (rf *Raft)setTerm(term int ){
    rf.currentTerm=term
}
/** election for leader
 */
func (rf *Raft)election()  {
    var result bool
    for  {
        timeout :=randRage(150,300)
        rf.lastMessaheTime=millisecond()
        select {
        case <-time.After(time.Duration(timeout)*time.Microsecond):
            fmt.Println("當前節(jié)點狀態(tài)為:",rf.state)
        }
        result=false
        for !result{
            result=rf.election_one_round(&leader)
        }
    }
}

/* randRange set time out
 */
func randRage(min,max int64) int64  {
    return  rand.Int63n(max-min)+min
}
/**get the lastMessage send time
 */
func millisecond() int64 {
    return time.Now().UnixNano()/int64(time.Microsecond)
}
/**
implementation of select leader
 */
func (rf *Raft)election_one_round(leader *Leader) bool  {
    //set time out
    var timeout int64
    timeout = 100
    //number of vote
    var vote int
    //heartbeat
    var triggerHeartbeat bool
    var success bool
    //time
    last :=millisecond()
    //change the item be canditate
    rf.mu.Lock()
    //change state
    rf.becomeCandidate()
    rf.mu.Unlock()
    fmt.Println("staet electing leader")
    //range all item
    for{
        for i:=0;i<raftCount;i++ {
            if i!=rf.me{
                // canvass vote
                go func() {
                    if leader.LeaderId<0{
                            rf.electCh<-true
                    }
                }()
            }
        }
        vote  = 1
        for i:=0;i<raftCount;i++{
            //calculate the number of vote
            select {
            case ok:=<-rf.electCh:
                if ok{
                    //vote number add 1
                    vote++
                    //if vote great than node one-second ,successful
                    success=vote>raftCount/2
                    if success&&!triggerHeartbeat{
                        //change be the leader success
                        //trigger the hearbeat detection
                        triggerHeartbeat =true
                        rf.mu.Lock()
                        rf.becomeLeader()
                        rf.mu.Unlock()
                        rf.heartBeat<- true
                        fmt.Println(rf.me,"號節(jié)點成為leader")
                        fmt.Println("leader 開始發(fā)送心跳信號")
                    }
                }
            }
        }
        //final check
        //if don't time out and the vote great then node one-second ,than impelmention select leader successful.
        if timeout+last<millisecond()||(vote>raftCount/2||rf.currentLeader>-1){
            break
        }else{
            select {
            case <-time.After(time.Duration(10)*time.Microsecond):
            }
        }

    }
    return success

}

/**
change state with candidate
 */
func (rf *Raft)becomeCandidate()  {
    rf.state=1
    rf.setTerm(rf.currentTerm+1)
    rf.votedFor=rf.me
    rf.currentLeader=-1
}

/**
change state with leader
 */
func(rf *Raft)becomeLeader(){
 rf.state=2
 rf.currentLeader=rf.me
}

/**
  leader send heartBeat
  complete data synchronization
 */
func (rf *Raft) sendLeaderHeartBeat()  {
    //infinity loop
    for{
        select {
        case <-rf.heartBeat:
            rf.sendAppendEntriesImpl()
        }
    }
}
/**
return info to the leader
 */
func (rf *Raft)sendAppendEntriesImpl()  {
    if rf.currentLeader == rf.me{
        //the time  is  leader
        //number of record to confirm single node
        var success_count =0
        for i:=0;i<raftCount;i++{
            if i!=rf.me{
                go func() {
                    rf.heartbeatRe<-true
                }()
            }
            //complete the sigle node of return confirm
            for i:=0;i<raftCount;i++{
                select {
                case ok:=<-rf.heartbeatRe:
                    if ok{
                        success_count++
                        if success_count>raftCount/2{
                            fmt.Println("投票選舉成功,心跳信號Ok")
                            log.Fatal("程序結束")
                        }
                    }

                }
            }
        }
    }
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容