raft 算法实现

作者: 吴佳浩 | 来源:发表于2023-03-26 20:01 被阅读0次
//1.实现3节点选举
//2.改造代码成分布式选举代码,加入Rpc调用
//3.演示完整代码 自动选主  日志复制


//定义3节点常量
const raftCount =3

/**
    Leader对象
    Term int             任期 还没上任为0
    LeaderId int         leaderId 编号 没有编号为-1
 */
type Leader struct {
    Term int
    LeaderId int
}

/**raft的声明

锁                                                     mu                             sync.Mutex
节点编号                                               me                              int
当前任期                                               currentTerm               int
为哪个节点投票 -1代表谁都不投             vatedFor                     int
0.follower 1.candidate 2.leader  state                        int
发送最后一条消息的时间                         lastMessaheTime           int64
当前节点的leader                               currentLeader             int
节点间发送信息的通道                            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() {
    //过程:有三个节点,最初都是follower
    //如果有candidate状态,进行投票和拉票
    //会产生leader
    //会产生3个节点
    for i:=0;i<raftCount;i++{
        //穿件三个raft节点
        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())
    //选举协程
     go rf.election()
    //心跳检测协程
    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("当前节点状态为:",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,"号节点成为leader")
                        fmt.Println("leader 开始发送心跳信号")
                    }
                }
            }
        }
        //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("程序结束")
                        }
                    }

                }
            }
        }
    }
}

相关文章

  • 分布式系统-一致性算法-Raft算法

    Raft算法介绍 raft是一个协议,可以用来实现分布式系统的一致性。 raft算法中节点的三种状态 Leader...

  • 分布式选举-Raft算法-2 Leader选举 代码实现

    Raft Leader选举实现 设定集群中有5个节点,通过Raft算法实现选主。节点之间的通信使用的是自我实现的R...

  • Raft算法解析

    什么是Raft算法? Raft算法是用于解决分布式系统中一致性问题的算法。在Raft算法之前,Lamport老爷爷...

  • 分布式共识算法

    导读: 拜占庭将军问题 1.概述 2.raft 一致性算法 2.1 raft算法选主流程 2.2 raft算法的数...

  • 共识算法:Raft

    共识算法:RaftRaft 官网Raft 原理动画 (推荐看看Raft 算法解析图片来源

  • Raft算法的理解

    简介 Raft 是一种通过日志复制来实现的一致性算法,提供了和Paxos 算法相同的功能和性能Raft 将一致性问...

  • raft算法笔记

    raft算法动画地址:http://thesecretlivesofdata.com/raft/raft是一个共识...

  • Raft 算法工程实现

    1、前言 此工程实现来自 github 链接:https://github.com/stateIs0/lu-raf...

  • Raft 算法浓缩

    Raft 算法浓缩总结 Raft 论文给出了下面的表格,用于总结 Raft 算法精华 。 实际上,这些精华都是一条...

  • RAFT算法

    RAFT算法: RAFT算法引用原文论文翻译的第一句话:RAFT是一种为了管理复制日志的一致性算法(https:/...

网友评论

    本文标题:raft 算法实现

    本文链接:https://www.haomeiwen.com/subject/gjhkrdtx.html