云原生 etcd 系列-8|Quorum 和唱票那回事

2024-03-26 15:40

本文主要是介绍云原生 etcd 系列-8|Quorum 和唱票那回事,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

云原生 etcd 系列-8|Quorum 和唱票那回事

Image

关于 Quorum 的两个维度

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

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

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

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

  1. 既然是选举过程,那怎么选举结果唱票的
  2. 既然是运行过程,那集群的这些节点怎么确认集群的 commit 位置

有选举自然有唱票

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

etcd 里面也有选举,也就是 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{} ,不占空间,一举两得。

唱票和集群 commit 的实现就是它的方法,我们先看下唱票的实现:

// 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]++} else {// 投票拒绝的ny[0]++}}q := len(c)/2 + 1if ny[1] >= q {// 选举成功:得票数超过半数,,比如 votes => [yes, yes, yes]return VoteWon}if ny[1]+missing >= q {// 未知情况:不确定成功,也不确定失败return VotePending}// 选举失败return VoteLost
}

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

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

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

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

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

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

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

// etcd/raft/quorum/majority.go
func (c MajorityConfig) CommittedIndex(l AckedIndexer) Index {// 遍历集群节点:取出每个节点的 commitfor 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 位置取出来,是这样的:

Image

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

Image

总结

  1. Quorum 机制是分布式系统中很重要的理论部分,这是一个关于多数派的机制。etcd 关于多数派有两个方面:Leader 选举和 raft 日志运行;
  2. etcd 的唱票实现非常简单,就是一个计数“正”字的实现,用一个 map 记录集群的节点,投票计数超过多数则胜出;
  3. etcd 确认集群 commit 位置则是先把每个节点的 commit 位置放在数组,然后排个序,然后取中间位置,这个位置就是集群的 commit 位置
  4. 多数节点 commit 过的日志才是集群 commit 的位置,集群 commit 的日志才能 apply ,这个要记住喽;
  5. 集群 commit 位置将由 Leader 通过心跳或者日志复制的消息告诉其他节点;

这篇关于云原生 etcd 系列-8|Quorum 和唱票那回事的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/848993

相关文章

k8s部署MongDB全过程

《k8s部署MongDB全过程》文章介绍了如何在Kubernetes集群中部署MongoDB,包括环境准备、创建Secret、创建服务和Deployment,并通过Robo3T工具测试连接... 目录一、环境准备1.1 环境说明1.2 创建 namespace1.3 创建mongdb账号/密码二、创建Sec

centos7基于keepalived+nginx部署k8s1.26.0高可用集群

《centos7基于keepalived+nginx部署k8s1.26.0高可用集群》Kubernetes是一个开源的容器编排平台,用于自动化地部署、扩展和管理容器化应用程序,在生产环境中,为了确保集... 目录一、初始化(所有节点都执行)二、安装containerd(所有节点都执行)三、安装docker-

Golang使用etcd构建分布式锁的示例分享

《Golang使用etcd构建分布式锁的示例分享》在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统,分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要,它有助于维护一致性,防止竞... 目录引言环境准备新建Go项目实现加锁和解锁功能测试分布式锁重构实现失败重试总结引言我们将使用Go作

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟