云原生 Etcd 系列之Quorum 和唱票那回事

  发布时间:2026-11-12   作者:玩站小弟   我要评论
你是凶手电影。

 

关于 Quorum 的两个维度

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

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

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

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

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

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

有选举自然有唱票

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

etc云原d 里面也有选举,也就是 Leader 的选举。Leader 获胜的依据是的票满足大多数,也就是满足 quorum 机制。

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

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

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

来看看 etcd 的唱票

选举属于 quorum 机制,代码位于 etcd/raft/quorum/ 下。quorum 的核心实现在 MajorityConfig 的结构体,其实就是个 map 的封装:

type MajorityConfig map[uint64]struct{} 

这个 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&nbsEtp;的数组     ny := [2]int{}     // 遍历集群节点     for id := range c {         v, ok := votes[id]       &ncdbsp; if !ok {             // 暂时没投票的             missing++             continue    & 系nbsp;    }         if v {             // 投票赞同的             ny[1]++      &n列之bsp;  } else {             // 投票拒绝的             ny[0]++         }     }   Qu  q := len(c)/2 + 1     if ny[1] >= q {         // 选举成功:得票数超过半数,,比如 votes => [yes, yes, yes]         return VoroteWon     }     if ny[1]+missing >= q {         // 未知情况:不确定成功,也不确定失败         return VotePending     }   um;  // 选举失败     return VoteLost } 

唱票的实现很简单,就如下几个步骤:

遍历集群节点; 统计谁赞同了、谁拒绝了、谁还没投票; 唱票的结果有三种:成功,失败,待定; 赞同投票的超过半数( len(c)/2+1 ),则胜利;

这实现可太简单了,就是一个遍历投票结果,写“正”字,“正”字超过半数则胜出。

集群的节点怎么确认集群的 commit 位置?

集群内被多数节点 commit 的位置才是集群的 commit 点。也就是说这个也需要满足 quorum 。这个就有意思了。

关键步骤:排序,然后取中间的位置。

取的这个中间的位置就是满足 和 quorum 的 commit 。

// etcd/raft/quorum/majority.go func (c MajorityConfig) CommittedIndex(l AckedIndexer) Index {     // 遍历集群节点:取出每个节点的 commit     for id := range c {    唱票;     if idx, ok := l.AckedIndex(id); ok {             srt[i] = uint64(idx)             i--     那回;    }     }     // 排个序     insertionSort(srt)      // 取中间,这个位置就是大多数 commit 的位置,属集群共识     pos := n - (n/2 + 1)  云原;   return Index(srt[pos]) } 

这个实现就很有意思了,捞出每个节点当前的 commit 位置,组成一个数组,然后给这个数组排个序,取中间的位置。这个位置就是集群的 commit 位置,也就是 apply 的位置。

先把集群每个节点的 commit 位置取出来,是这样的:

后来排个序是这样的,黑色的节点 commit 位置则是集群的 commit 位置:

总结

Quorum 机制是分布式系统中很重要的理论部分,这是一个关于多数派的机制。etcd 关于多数派有两个方面:Leader 选举和 raft 日志运行;

etcd 的唱票实现非常简单,就是一个计数“正”字的实现,用一个 map 记录集群的节生 点,投票计数超过多数则胜出;

etcd 确认集群 commit 位置则是先把每个节点的 commit 位置放在数组,然后排个序,然后取中间位置,这个位置就是集群的 commit 位置;

多数节点 commit 过的日志才是集群 commit 的位置,集群 commit 的日志才能 apply ,这个要记住喽;

集群 commit 位置将由 Leader 通过心跳或者日志复制的消息告诉其他节点;

 

  • Tag:

相关文章

  • 贝索斯将于7月5日卸任亚马逊CEO上热搜 网友:反正钱已经多的花不完了

    新浪科技讯 5月27日上午消息,贝索斯将于7月5日卸任亚马逊CEO登上微博热搜,引发热议。 贝索斯周三在以虚拟形式召开的亚马逊年度股东大会上表示,自己将于7月5日卸任,届时该公司的云计算负责人安迪·贾
    2026-11-12
  • 微软将于1月27日发布2021财年第二季度财报

    新浪科技讯 北京时间1月19日晚间消息,微软宣布,将于当地时间1月26日(北京时间1月27日)发布2021财年第二季度财报。 财报发布后,微软将于美国太平洋时间1月26日下午2点30分至3点30分(北
    2026-11-12
  • IDC:中国品牌升腾(Centerm)拿下瘦客户机市场第一,超越长期领先的戴尔和惠普

    3 月 14 日消息,根据国际数据公司 IDC 全球季度企业客户端设备跟踪报告,2022 年,瘦客户机设备的全球出货量下降了 7.9%,在 2022 年第四季度下降了 24%,这是瘦客户机设备出货量连
    2026-11-12
  • 基于kubernetes构建混合云的利弊

    在过去一年里,混合云被称为是企业开启云端转型的最佳选择。问题是,我们将以何种方式开启混合云之旅? 纵观混合云平台及解决方案,无非分两大类。一类是基于Kubernetes构建的;另一类是不基于Kuber
    2026-11-12
  • AI技术加入数据中心节能新战场

    前言: 2020年,数据中心建设被中央正式列入新基建战略,被视为新基建的基础设施、经济高质量发展的数字底座。 然而随着数据流量呈指数增长,数据中心设备功耗也在不断攀升,电能消耗数目弥巨和运营成本居高不
    2026-11-12
  • 机票搜索量猛增7倍 携程引入阿里云Lindorm数据库保障用户体验

    12月13日消息,近日来,各大旅游平台迎来复苏,机票、火车票和酒店关注度大涨,仅携程和去哪儿平台,机票的瞬时搜索量就增长了7倍,火车票搜索量增长5倍,春节期间搜索量达到近三年的峰值。 为了保障用户的搜
    2026-11-12

最新评论