2018-05-24raft實(shí)現(xiàn)代碼

1.go語(yǔ)言實(shí)現(xiàn)raft分發(fā)原理
main.go 文件代碼如下

package main

import (
    "sync"
    "math/rand"
    "fmt"
    "time"
    "go/ast"
)

// 設(shè)置節(jié)點(diǎn)的個(gè)數(shù)為3
const raftCount  =3
// 聲明leader
type AppendEntiresArgs struct {
    Term int// 第幾任領(lǐng)導(dǎo)
    leaderId  int//設(shè)置領(lǐng)導(dǎo)編號(hào)
}
// 創(chuàng)建一個(gè)領(lǐng)導(dǎo)對(duì)象
var args   =AppendEntiresArgs{0,-1}
// 聲明節(jié)點(diǎn)類(lèi)型
type Raft struct {
    // 線程鎖
    mu  sync.Mutex
    // 節(jié)點(diǎn)編號(hào)
    me int
    //當(dāng)前領(lǐng)導(dǎo)期數(shù)
    currentTerm int
    // 為哪個(gè)節(jié)點(diǎn)投票
    votedFor int
    //當(dāng)前節(jié)點(diǎn)的狀態(tài)
    state int// 0 跟隨者 1候選人 2就是領(lǐng)導(dǎo)
    // 厚厚一天發(fā)送消息時(shí)間
    lastMessageTime  int64
    // 節(jié)點(diǎn)間發(fā)送消息的通道
    message  chan bool
    // 選舉通道
    eclectCh chan bool
    // 心跳信號(hào)通道
    heartBeat chan bool
    // 返回心跳信號(hào)
    heartBeatRe chan  bool
    // 超時(shí)時(shí)間
    timeout  int

    // 設(shè)置當(dāng)前節(jié)點(diǎn)的領(lǐng)導(dǎo)
  currentLeader int
}
// 產(chǎn)生隨機(jī)值
func  randRange(min,max int64)int64  {
    return  rand.Int63n(max-min)+min
}
// 打印當(dāng)前時(shí)間
func printTime()  {
    fmt.Printf("%s",time.Now().String())
}

// 獲取當(dāng)前時(shí)間的ms
func millisecond()int64  {
    return  time.Now().UnixNano()/int64(time.Millisecond)
}

func  main()  {
    // 創(chuàng)建三個(gè)節(jié)點(diǎn)
    for i:=0;i<raftCount ;i++  {
        // 創(chuàng)建三個(gè)raft
        Make(i)

    }
    for{

    }
}
// 通過(guò)make函數(shù)創(chuàng)建raft節(jié)點(diǎn)的對(duì)象
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)
    // 創(chuàng)建通道對(duì)象
    rf.eclectCh = make(chan bool)
    rf.message = make(chan  bool)
    rf.heartBeat = make(chan bool)
    rf.heartBeatRe = make(chan bool)
    rand.Seed(time.Now().UnixNano())

    go rf.sendLeaderHeartBeat()
    go rf.election()

    return rf
}
// 創(chuàng)建raft對(duì)象的方法
func  (rf *Raft) setTerm(term int)  {
    rf.currentTerm = term
}
// 設(shè)置節(jié)點(diǎn)發(fā)送心跳信號(hào)的方法
func (rf *Raft)sendLeaderHeartBeat()  {
}
//設(shè)置節(jié)點(diǎn)投票的方法
func (rf *Raft)election ()  {
    // 設(shè)置標(biāo)簽
    var result bool
    for  {
        // 設(shè)置超時(shí)時(shí)間
        timeout := randRange(150,300)
        // 設(shè)置每個(gè)節(jié)點(diǎn)的時(shí)間
        rf.lastMessageTime = millisecond()
        select {
        // 延遲等待
        case <-time.After(time.Duration(timeout)*time.Millisecond):
            fmt.Println(rf.state)// 打印當(dāng)前節(jié)點(diǎn)的狀態(tài)
        }
        result= false
        for !result{
            // 選擇誰(shuí)作為leader
            result = rf.election_one_round(&args)
        }
    }
}
// 選擇誰(shuí)為leader
func (rf *Raft)election_one_round(args *AppendEntiresArgs)bool  {
    var  timeout int64
    var done int
    // 是否開(kāi)始心跳信號(hào)的產(chǎn)生
    var  triggerHeartbeat bool
    last := millisecond()
    timeout = 100
    // 信號(hào)變量標(biāo)簽
    success :=false
    // 修改raft節(jié)點(diǎn)的狀態(tài)為candidate候選人狀態(tài)
    rf.mu.Lock()
    rf.becomeCandidate()
    rf.mu.Unlock()

    fmt.Println("start electing leader")
    for  {
        for i:=0;i<raftCount ;i++  {
            if i!= rf.me {
                //拉選票
             printTime()
             go func() {
                 if args.leaderId <0 {
                    // 設(shè)置此節(jié)點(diǎn)開(kāi)始選舉
                    rf.eclectCh <- true
                 }
             }()
            }
        }
        // 設(shè)置投票數(shù)量
        done =0
        triggerHeartbeat = false
        for i:=0;i<raftCount-1 ;i++  {
            // 計(jì)算一下投票的數(shù)量
            //raftCount-1 把自己去掉
            select {
            case ok:= <-rf.eclectCh:
                if ok {
                    done ++
                    success = done>raftCount/2
                    if success && !triggerHeartbeat {
                        // 選舉成功了
                        triggerHeartbeat = true
                        rf.mu.Lock()
                        rf.brcomeLeader()
                        rf.mu.Unlock()
                        // 由leader向其他節(jié)點(diǎn)發(fā)送心跳信號(hào)
                        rf.heartBeat <- true
                        fmt.Println("leader發(fā)送心跳信號(hào)")
                    }
                }
            }
        }
        if(timeout+last <millisecond()||(done>raftCount/2 || rf.currentLeader>-1)) {
            break
        }else {
            select {
            // 延時(shí)操作
            case <-time.After(time.Duration(10)*time.Millisecond):      
            }
        }
    }
    return success
}
func(rf *Raft) becomeCandidate()  {
    rf.state  = 1
    rf.setTerm(rf.currentTerm +1)
    rf.votedFor = rf.me
    rf.currentLeader = -1
}
func (rf *Raft)brcomeLeader()  {
    rf.state = 2
    rf.currentLeader = rf.me
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咨演,一起剝皮案震驚了整個(gè)濱河市蚯斯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拍嵌,老刑警劉巖横辆,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異困肩,居然都是意外死亡脆侮,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)潭枣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人退敦,你說(shuō)我怎么就攤上這事蚣抗。” “怎么了翰铡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵锭魔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我迷捧,道長(zhǎng),這世上最難降的妖魔是什么笙蒙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任捅位,我火速辦了婚禮搂抒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘求晶。我一直安慰自己,他們只是感情好矩屁,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布蚜锨。 她就那樣靜靜地躺著,像睡著了一般郭膛。 火紅的嫁衣襯著肌膚如雪氛悬。 梳的紋絲不亂的頭發(fā)上耘柱,一...
    開(kāi)封第一講書(shū)人閱讀 52,682評(píng)論 1 312
  • 那天调煎,我揣著相機(jī)與錄音己肮,去河邊找鬼。 笑死谎僻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赤拒。 我是一名探鬼主播诱鞠,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼航夺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了敷存?” 一聲冷哼從身側(cè)響起堪伍,我...
    開(kāi)封第一講書(shū)人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤帝雇,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后尸闸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年宙址,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了调卑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大咱。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡注益,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桶蛔,到底是詐尸還是另有隱情挂疆,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布欺抗,位于F島的核電站强重,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏间景。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一圾亏、第九天 我趴在偏房一處隱蔽的房頂上張望封拧。 院中可真熱鬧,春花似錦曹铃、人聲如沸捧杉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)仔涩。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蓖乘,已是汗流浹背韧骗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留些侍,地道東北人政模。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像耗式,于是被迫代替她去往敵國(guó)和親趁猴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 說(shuō)明本次redis集群安裝在rhel6.8 64位機(jī)器上娱挨,redis版本為3.2.8捕犬,redis的gem文件版本為...
    讀或?qū)?/span>閱讀 14,829評(píng)論 3 9
  • 全部代碼在我的GitHub碉碉,本文只做分析。 簡(jiǎn)介 該部分主要是要求完成 server 選舉的相關(guān)功能誉裆,暫時(shí)不牽涉到...
    找不到工作閱讀 4,411評(píng)論 2 5
  • consul agent 分client server client 一般部署在靠近應(yīng)用的地方,甚至本機(jī)用于對(duì)應(yīng)用...
    wwq2020閱讀 3,628評(píng)論 0 0
  • Notes Section 2, Program Structure nested block in if-els...
    keysaim閱讀 1,164評(píng)論 0 1
  • 隨便寫(xiě)點(diǎn)東東,鍛煉一下自己殘疾的手指庇配,總是擔(dān)心不打字,今后連打字的功能都會(huì)喪失耀鸦。 其實(shí),頁(yè)沒(méi)什么好寫(xiě)的袖订。 最近突然...
    虞姬Mermaid閱讀 234評(píng)論 0 0