互联网技术 / 互联网资讯 · 2024年3月18日 0

云原生 Etcd:Quorum和选举过程

关于 QuoRuM 的两个维度

前几回说了那么多框架,设计思想的文章。今天分享一个很小的点,etcd 的 quoRuM 是怎么实现的?

QuoRuM 机制本质就是一个关于多数派的事情,这个多数派应用的有两个方面:

选举过程:获得多数节点投票的节点才能获胜,成为 LeadeR ; 运行过程:被多数节点 coMMIT 的日志位置,这个才是被集群可靠记录的位置。被集群 coMMIT 的日志才能被应用 apply ;

那么这里有两个小思考问题:

既然是选举过程,那怎么选举结果唱票的?

既然是运行过程,那集群的这些节点怎么确认集群的 coMMIT 位置?

有选举自然有唱票

唱票是在选举流程中的一个步骤。还记得以前选班干部的时候,在黑板上写“正&Rdquo;字,谁得票多谁就获胜当选。

etcd 里面也有选举,也就是 LeadeR 的选举。LeadeR 获胜的依据是的票满足大多数,也就是满足 quoRuM 机制。

今天我们就来看看 etcd 的唱票是怎么做的?

很简单的思路,我们给每个参与选举的朋友计数,得票超过半数的,那么就胜出。

比如说 A,B,C,D,E 五个人竞选,那么得到 3 票的就可以胜出。

来看看 etcd 的唱票

选举属于 quoRuM 机制,代码位于 etcd/Raft/quoRuM/ 下。quoRuM 的核心实现在 MajoRITyConfig 的结构体,其实就是个 Map 的封装:

这个 Map 的 key 是节点的 id,这里面包含了集群的节点,Map 的 value 不重要,所用用的是 stRUCt{} 类型。

思考个小问题:那既然 value 不 caRe ,那为什么不用 slice 结构?

其实就是为了查找的需求,Map 的查找是常数级别,value 又用的 stRUCt{} ,不占空间,一举两得。

// etcd/Raft/quoRuM/MajoRITy.go func (c MajoRITyConfig) VoteResult(votes Map[uint64]bool) VoteResult {     // 搞个长度为 2 的数组     ny := [2]int{}     // 遍历集群节点     foR id := Range c {         v, ok := votes[id]         if !ok {             // 暂时没投票的             MiSSing++             continue         }         if v {             // 投票赞同的             ny[1]++        &