日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Quorum 和唱票那回事

發(fā)布時(shí)間:2024/8/23 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Quorum 和唱票那回事 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者 | 奇伢

來源 | 奇伢云存儲(chǔ)

關(guān)于 Quorum 的兩個(gè)維度

前幾回說了那么多框架,設(shè)計(jì)思想的文章。今天分享一個(gè)很小的點(diǎn),etcd 的 quorum 是怎么實(shí)現(xiàn)的?

Quorum 機(jī)制本質(zhì)就是一個(gè)關(guān)于多數(shù)派的事情,這個(gè)多數(shù)派應(yīng)用的有兩個(gè)方面:

  • 選舉過程:獲得多數(shù)節(jié)點(diǎn)投票的節(jié)點(diǎn)才能獲勝,成為 Leader ;

  • 運(yùn)行過程:被多數(shù)節(jié)點(diǎn) commit 的日志位置,這個(gè)才是被集群可靠記錄的位置。被集群 commit 的日志才能被應(yīng)用 apply ;

  • 那么這里有兩個(gè)小思考問題:

  • 既然是選舉過程,那怎么選舉結(jié)果唱票的

  • 既然是運(yùn)行過程,那集群的這些節(jié)點(diǎn)怎么確認(rèn)集群的 commit 位置

  • 有選舉自然有唱票

    唱票是在選舉流程中的一個(gè)步驟。還記得以前選班干部的時(shí)候,在黑板上寫“正”字,誰得票多誰就獲勝當(dāng)選。

    etcd 里面也有選舉,也就是 Leader 的選舉。Leader 獲勝的依據(jù)是的票滿足大多數(shù),也就是滿足 quorum 機(jī)制。

    今天我們就來看看 etcd 的唱票是怎么做的?

    很簡單的思路,我們給每個(gè)參與選舉的朋友計(jì)數(shù),得票超過半數(shù)的,那么就勝出。

    比如說 A,B,C,D,E 五個(gè)人競選,那么得到 3 票的就可以勝出。

    來看看 etcd 的唱票

    選舉屬于 quorum 機(jī)制,代碼位于 etcd/raft/quorum/ 下。quorum 的核心實(shí)現(xiàn)在 MajorityConfig 的結(jié)構(gòu)體,其實(shí)就是個(gè) map 的封裝:

    type?MajorityConfig?map[uint64]struct{}

    這個(gè) map 的 key 是節(jié)點(diǎn)的 id,這里面包含了集群的節(jié)點(diǎn),map 的 value 不重要,所用用的是 struct{} 類型。

    思考個(gè)小問題:那既然 value 不 care ,那為什么不用 slice 結(jié)構(gòu)?

    其實(shí)就是為了查找的需求,map 的查找是常數(shù)級別,value 又用的 struct{} ,不占空間,一舉兩得。

    唱票和集群 commit 的實(shí)現(xiàn)就是它的方法,我們先看下唱票的實(shí)現(xiàn):

    //?etcd/raft/quorum/majority.go func?(c?MajorityConfig)?VoteResult(votes?map[uint64]bool)?VoteResult?{//?搞個(gè)長度為?2?的數(shù)組ny?:=?[2]int{}//?遍歷集群節(jié)點(diǎn)for?id?:=?range?c?{v,?ok?:=?votes[id]if?!ok?{//?暫時(shí)沒投票的missing++continue}if?v?{//?投票贊同的ny[1]++}?else?{//?投票拒絕的ny[0]++}}q?:=?len(c)/2?+?1if?ny[1]?>=?q?{//?選舉成功:得票數(shù)超過半數(shù),,比如 votes =>?[yes, yes, yes]return?VoteWon}if?ny[1]+missing?>=?q?{//?未知情況:不確定成功,也不確定失敗return?VotePending}//?選舉失敗return?VoteLost }

    唱票的實(shí)現(xiàn)很簡單,就如下幾個(gè)步驟:

  • 遍歷集群節(jié)點(diǎn);

  • 統(tǒng)計(jì)誰贊同了、誰拒絕了、誰還沒投票;

  • 唱票的結(jié)果有三種:成功,失敗,待定;

  • 贊同投票的超過半數(shù)( len(c)/2+1 ),則勝利;

  • 這實(shí)現(xiàn)可太簡單了,就是一個(gè)遍歷投票結(jié)果,寫“正”字,“正”字超過半數(shù)則勝出。

    集群的節(jié)點(diǎn)怎么確認(rèn)集群的 commit 位置?

    集群內(nèi)被多數(shù)節(jié)點(diǎn) commit 的位置才是集群的 commit 點(diǎn)。也就是說這個(gè)也需要滿足 quorum 。這個(gè)就有意思了。

    關(guān)鍵步驟:排序,然后取中間的位置。

    取的這個(gè)中間的位置就是滿足 quorum 的 commit 。

    //?etcd/raft/quorum/majority.go func?(c?MajorityConfig)?CommittedIndex(l?AckedIndexer)?Index?{//?遍歷集群節(jié)點(diǎn):取出每個(gè)節(jié)點(diǎn)的 commitfor?id?:=?range?c?{if?idx,?ok?:=?l.AckedIndex(id);?ok?{srt[i]?=?uint64(idx)i--}}//?排個(gè)序insertionSort(srt)//?取中間,這個(gè)位置就是大多數(shù)?commit?的位置,屬集群共識pos?:=?n?-?(n/2?+?1)return?Index(srt[pos]) }

    這個(gè)實(shí)現(xiàn)就很有意思了,撈出每個(gè)節(jié)點(diǎn)當(dāng)前的 commit 位置,組成一個(gè)數(shù)組,然后給這個(gè)數(shù)組排個(gè)序,取中間的位置。這個(gè)位置就是集群的 commit 位置,也就是 apply 的位置。

    先把集群每個(gè)節(jié)點(diǎn)的 commit 位置取出來,是這樣的:


    后來排個(gè)序是這樣的,黑色的節(jié)點(diǎn) commit 位置則是集群的 commit 位置



    總結(jié)

  • Quorum 機(jī)制是分布式系統(tǒng)中很重要的理論部分,這是一個(gè)關(guān)于多數(shù)派的機(jī)制。etcd 關(guān)于多數(shù)派有兩個(gè)方面:Leader 選舉和 raft 日志運(yùn)行;

  • etcd 的唱票實(shí)現(xiàn)非常簡單,就是一個(gè)計(jì)數(shù)“正”字的實(shí)現(xiàn),用一個(gè) map 記錄集群的節(jié)點(diǎn),投票計(jì)數(shù)超過多數(shù)則勝出;

  • etcd 確認(rèn)集群 commit 位置則是先把每個(gè)節(jié)點(diǎn)的 commit 位置放在數(shù)組,然后排個(gè)序,然后取中間位置,這個(gè)位置就是集群的 commit 位置

  • 多數(shù)節(jié)點(diǎn) commit 過的日志才是集群 commit 的位置,集群 commit 的日志才能 apply ,這個(gè)要記住嘍;

  • 集群 commit?位置將由 Leader?通過心跳或者日志復(fù)制的消息告訴其他節(jié)點(diǎn);

  • 往期推薦

    虛幻引擎5上的《黑客帝國》全新體驗(yàn),愛了愛了

    元宇宙真的是割韭菜嗎?

    Redis會(huì)遇到的坑,你踩過幾個(gè)?

    核彈級漏洞,把log4j扒給你看!

    點(diǎn)分享

    點(diǎn)收藏

    點(diǎn)點(diǎn)贊

    點(diǎn)在看

    總結(jié)

    以上是生活随笔為你收集整理的Quorum 和唱票那回事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。