【大数据】Zookeeper 集群及其选举机制

Zookeeper 集群及其选举机制

  • 1.安装 Zookeeper 集群
  • 2.如何选取 Leader

1.安装 Zookeeper 集群

我们之前说了,Zookeeper 集群是由一个领导者(Leader)和多个追随者(Follower)组成,但这个领导者是怎么选出来的呢?我们貌似没有在配置文件中看到有关领导者和追随者的参数啊?

在此之前先来看看 Zookeeper 内部的一些机制:

  • 半数机制:只要有半数以上的节点存活,则集群可用,所以 Zookeeper 集群的节点数量适合为奇数。
  • 虽然在配置文件中没有指定领导者和追随者,但 Zookeeper 在工作时,有一个节点为 Leader,其它则为 Follower,而 Leader 是通过内部的选举机制临时产生的。

那么领导者到底是怎么选出来的呢?很简单,每台服务器都有一个 id(这里的 id 后面说),当启动的服务器超过半数的时候,就会选择 id 最大的 Server 成为领导者。比如有五台服务器,半数就是 2.5 2.5 2.5,因此当启动三台的时候就可以选出领导者。至于剩余的两台,启动之后只能成为追随者,因为领导者已经选出来了。关于这里的细节,一会儿再详细聊。

那么怎么指定服务器的 id 呢?还记得配置文件中的 dataDir 参数吗,在该参数指定的目录下创建一个 myid 文件(文件必须叫这个名字),然后在里面写上服务器的 id 即可。

[root@satori zkData]# echo 2 > myid

这里给 id 设置为 2,因为一会要搭建由三个节点组成的集群,而我希望当前节点成为 Leader,所以它的 id 应该为 2,其它的两个节点的 id 显然分别为 1 和 3。这样按着 id 从小到大的顺序启动时,该节点就会成为 Leader。

下面来我们来搭建 zookeeper 集群,总共三个节点:

  • IP:82.157.146.194,主机名:satori
  • IP:121.37.165.252,主机名:koishi
  • IP:123.60.7.226,主机名:marisa

satori 节点就是当前一直在用的节点,剩余的两个节点的 Zookeeper 也已经安装完毕。那么问题来了,我们要如何将这三个节点组成一个集群呢?显然还需要修改配置文件,先在 satori 节点进行修改。

# koishi 节点
server.1=121.37.165.252:2888:3888
# satori 节点
server.2=0.0.0.0:2888:3888
# marisa 节点
server.3=123.60.7.226:2888:3888

将集群中都有哪些节点写在 zoo.cfg 中,解释一下具体含义,首先两个冒号把等号右边分成了三部分,第一部分就不用说了,IP 地址或者主机名,用于定位节点; 2888 2888 2888 是 Leader 和 Follower 交换信息 的端口,因为副本要进行同步; 3888 3888 3888交换选举信息 的端口,因为要选出 Leader。

然后我们注意到 satori 节点的 IP 设置成了 0.0.0.0,这是因为当前的三个节点不在同一个网段,IP 用的都是公网 IP,而公网 IP 在绑定服务的时候会失败。所以在绑定的时候,其它节点的 IP 要写成公网 IP,自身节点的 IP 要写成 0.0.0.0。因此其它两个节点的 zoo.cfg 文件就应该这么改:

########## koishi 节点配置 ##########
# koishi 节点
server.1=0.0.0.0:2888:3888
# satori 节点
server.2=82.157.146.194:2888:3888
# marisa 节点
server.3=123.60.7.226:2888:3888

########## marisa 节点配置 ##########
# koishi 节点
server.1=121.37.165.252:2888:3888
# satori 节点
server.2=82.157.146.194:2888:3888
# marisa 节点
server.3=0.0.0.0:2888:3888

但是在 生产中,一个集群内的节点应该都位于同一网段,然后将配置文件中的 IP 全部换成内网 IP 即可。这样彼此之间可以通过内网访问,而内网的访问速度要远远快于公网,并且还不需要走公网的流量。但我当前的三台云服务器不在同一个网段,所以只能用公网 IP,并且绑定的时候,将节点自身的 IP 换成 0.0.0.0

至于等号左边的 server. 是固定的,后面的数字表示节点的 id,而节点 id 我们说了,通过在 myid 文件中进行指定。而节点 id 决定了,最终由谁担任领导者。其中 satori 节点的 id 2 2 2,刚刚已经改过了,然后将 koishimarisa 两个节点的 id 分别改为 1 1 1 3 3 3,然后就大功告成了。

然后我们来启动 Zookeeper,由于 satori 节点的 Zookeeper 已经启动了,我们在修改完配置文件之后,需要重新启动。

在这里插入图片描述

但是我们查看状态的时候,发现出错了,相信原因很好想。因为配置文件中指定了三个节点,而剩余两个节点的 Zookeeper 还没启动。下面我们来启动一下,然后再次查看状态。

在这里插入图片描述

当剩余的两个节点启动之后,再次查看状态,发现 Mode 变成了 Leader。显然集群已经启动成功,至于剩余的两个节点,显然就是 Follower。

在这里插入图片描述
在这里插入图片描述
此时集群就启动成功了,但是关于领导者和追随者的选举问题,我们还得再说一说。

2.如何选取 Leader

领导者选举分为两种情况:

  • 集群第一次启动的时候,选举领导者。
  • 运行过程中领导者挂了,从追随者当中选择一个作为领导者。

我们先来看第一种情况,假设集群当中有 5 个节点,id 分别为 1 到 5,来看看选举过程是怎样的?这里 5 个节点按照 id 从小到大顺序启动。
在这里插入图片描述

  • 首先 server1 启动,发起一次选举,每个节点都有投票权,并且默认都会投给自己。此时 server1 1 1 1 票,但还不够半数以上( 3 3 3 票),选举无法完成,于是 server1 将状态保持为 LOOKING
  • 然后 server2 启动,再发起一次选举,重新投票。server1server2 仍会把票投给自己,然后再交换选票信息。由于 server1 发现 server2id 比自己大,于是会将自己的票改投给 server2。此时 server1 0 0 0 票,server2 2 2 2 票,但仍然没有哪个节点拥有超过半数的票,选举无法完成,server1server2 状态都保持为 LOOKING
  • 接下来 server3 启动,再发起一次选举,相信整个过程不需要解释了。老规矩还是先投给自己,再交换选票信息,然后 server1server2 发现自己的 id 都没有 server3 大,于是都会将票改投给 server3。此时 server1server2 的票数为 0 0 0server3 的票数为 3 3 3,由于 server3 的票数已超过半数,所以成功当选为 Leader,状态变为 LEADING。而 server1server2 则成为 Follower,状态改为 FOLLOWING
  • 所以 5 5 5 个节点,启动 3 3 3 个之后就能选择出 Leader。然后 server4 又启动了,于是也发起一次选举,并把票投给自己。但 server1server2server3 已经不是 LOOKING 状态,所以它们不会更改自己的选票信息,最终结果 server3 仍有 3 3 3 票,server4 只有 1 1 1 票。少数服从多数,于是会再将自己的选票交给 server3,成为 Follower,状态改为 FOLLOWING
  • 同理,最后 server5 启动,结果就是 server3 4 4 4 票,自己只有 1 1 1 票。少数服从多数,于是将自己的选票交给 server3,成为 Follower。

所以整个过程,关键点有两个

  • 每个 server 启动之后都会发起选举,并将票投给自己。然后交换选票信息,并将票投给 id 最大的 server
  • 一旦选择出 Leader,其它节点自动成为 Follower。而后启动的 server,不论 id 多大,也只能成为 Follower。

以上就是集群第一次启动的时候,选举领导者。

但如果在运行过程中,领导者挂了该怎么办呢?显然要再选举出一个新的领导者。所以当集群中的追随者发现自己连接不上领导者的时候,就会开始进入 Leader 选举,但此时是存在两种可能的。

  • 领导者真的挂了。
  • 领导者没有挂,只是追随者因为某些原因无法和领导者建立连接。比如 server5 发现连接不上 server3 了,于是它认为领导者挂了,便开启 Leader 选举。但事实上 server3 并没有挂,其它追随者都能正常连接,只是 server5 因为某些原因连接不上罢了。

先来解释第二种情况,server5 认为 server3 挂了之后,便会发起 Leader 选举,呼吁其它追随者进行投票。但是其它追随者发现领导者并没有挂,于是会拒绝 server5 的选举申请,并告知它当前已存在的领导者信息。对于 server5 而言,只需要和已存在的领导者重新建立连接,并进行数据同步即可。

server3:老子还没挂呢!!!😤

但如果是第一种情况,领导者真的挂了,该怎么办?比如这里的领导者 server3,在运行的时候,节点突然宕机了。

要解释这个问题,我们需要引入一些新的概念。

  • sid:就是我们一直说的服务器 id,用于唯一标识集群中的节点。
  • zxid:事务 id,客户端在发起一次写请求的时候,都会带有 zxid,用于标识一次服务器状态的变更。所以 Zookeeper 也是有事务的,保证每次写数据的时候,要么全部写完,要么不写,不会出现只写一半的情况。另外每个节点都有自己的 zxid,它们的值也不一定相同。
  • epoch:Leader 任期的编号,就好比古代皇帝,每个皇帝在当政的时候都有自己的年号。并且每投完一次票,这个编号就会增加。

现在假设 server3 挂了,那么要重新选举 Leader,而选举规则如下:

  • 先比较节点之间的 epochepoch 大的直接当选。
  • epoch 相同,再比较 zxidzxid 大的当选。
  • epochzxid 都相同,则比较 sidsid 大的当选。

关于这么做背后的原理,我们先暂且不表,等到后面介绍 Paxos 协议的时候再细说。而且这里的 epoch 具体是干什么用的,估计也有人不太清楚,这些我们也留到后面再说。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/295058.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【公有云】通过AWS Endpoint service Endpoint 实现跨VPC请求收敛

背景 公司两个AWS VPC有互通的需求,分别是PROD-VPC和PCI-VPC。PCI是Payment Card Industry的简称,通常PCI-VPC部署支付后端服务。关于PCI的相关资料参考AWS PCI DSS,Payment Card Industry 数据安全标准。 PROD服务请求PCI服务是跨VPC访问&…

Spring官方移除Java8

大家好我是苏麟 , 今天聊聊怎么继续使用Java8做项目 . 在做项目的时候突然发现Java8没了 , 我心想 : " 嗯? IDEA出毛病了?" ,经过我仔细检查原来是spring官方不支持Java8了 . IDEA 内置的 Spring Initializr 创建 Spring Boot 新项目时,没有 Java 8 的选…

2024年如何借用电商新零售破局?新型商业模式——乐享甄选竞拍模式

2024年如何借用电商新零售破局?新型商业模式——乐享甄选竞拍模式 背景:经历疫情三年的黑天鹅,消费者对未来收入预期和不自信等悲观情绪,从而使得“勒紧腰带,少消费,不消费”,以简单实用成为了新…

静态网页设计——贵州美食(HTML+CSS+JavaScript)

前言 声明:该文章只是做技术分享,若侵权请联系我删除。!! 感谢大佬的视频: https://www.bilibili.com/video/BV1vC4y1K7de/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术:HTMLCSSJS(…

企业选择通配符证书和多域名证书

随着互联网的发展,用户渐渐不再满足于只创建一个网站,因此,网站越来越多,管理多个网站的SSL证书的成本和时间也随之增加。为了节省管理多个站点的SSL证书的时间与成本,很多用户会选择通配符SSL证书与多域名SSL证书。这…

基于萤火虫算法优化的Elman神经网络数据预测 - 附代码

基于萤火虫算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于萤火虫算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于萤火虫优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&#x…

docker daemon.json配置bip项需要注意的地方

docker是现在部署服务比较常用的一种方式,但是docker0网络默认为172.17.x.x网段,172.17这个网段是私有化ip段,而且在企业内部使用比较常见的一个网段,docker0创建后会创建一个172.17网段的路由(可以通过ip route查看&a…

Jenkins分布式实现: 构建弹性和可扩展的CI/CD环境!

Jenkins是一个流行的开源持续集成(Continuous Integration,CI)和持续交付(Continuous Delivery,CD)工具,它通过自动化构建、测试和部署过程,帮助开发团队更高效地交付软件。Jenkins的…

Socks5代理ip和Https代理ip的区别,该如何选择?

Socks5代理和HTTPS代理都是计算机网络中的代理服务器,它们可以用于在客户端和其他服务器之间建立连接并充当中间人。 两种代理类型都有其优缺点和适用场景。 一、什么是Socks5代理 Socks5代理Socks5代理是一个网络协议,通过该协议可以建立TCP和UDP连接…

智慧校园全空间三维电子沙盘系统

一、概述 易图讯科技(www.3dgis.top)采用大数据、云计算、虚拟现实、物联网、AI等先进技术,自主可控高性能WebGIS可视化引擎,支持多用户客户端通过网络请求访问服务器地图和专题数据,提供地理信息数据、专题数据的并发…

2023-2024学年上学期算法设计与分析题期末考试模拟卷

2023-2024学年上学期算法设计与分析题期末考试模拟卷 文章目录 2023-2024学年上学期算法设计与分析题期末考试模拟卷单选题程序填空题输入格式:输出格式:输入样例1:输出样例1: 主观题 注意:该题集非标准答案,仅供参考,如果异议,请…

Linkage Mapper 工具参数详解——Centrality Mapper

【小白一学就会无需其他教程】此文档用于解析使用Linkage Mapper 各输入输出参数详情以及可能的影响,并介绍了如何解释模型输出结果和输出参数,适合刚入手的人。篇幅很长很啰嗦,是因为每个参数都解释的万分细致。 从以下链接中获取内容&…

针对CSP-J/S的冲刺练习:Day 4 提高题

一、审题 时间限制:1000ms 内存限制:256MB 平均AC率:7.89% 题目描述 输出一个n*n大小的螺旋矩阵。 螺旋矩阵的样子: 输入描述 共一行,一个正整数n,表示矩阵变长的长度 输出描…

LeetCode206链表反转

//我来理解一下运用递归求解 class Solution { public:ListNode* reverseList(ListNode* head) {//首先判断是否为最后一个元素if(head null|| head.next null){return head;//返回末尾元素}ListNode* receive;//此时进入循环的每一层都实现了temp接收head.next的结点进行…

HarmonyOS应用开发之DevEco Studio安装与初次使用

1、DevEco Studio介绍 DevEco Studio是基于IntelliJ IDEA Community开源版本打造,面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创建、开发、编译、调试、发布等E2E的HarmonyOS应用/服务的开发工具。…

MR实战:网址去重

文章目录 一、实战概述二、提出任务三、完成任务(一)准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 (二)实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建网址去重映射器类5、创建网址去重归并…

《现代C++语言核心特性解析》笔记(三)

二十四、三向比较&#xff08;C20&#xff09; 1. “太空飞船”&#xff08;spaceship&#xff09;运算符 C20标准新引入了一个名为“太空飞船”&#xff08;spaceship&#xff09;的运算符 <>&#xff0c;它是一个三向比较运算符。<> 之所以被称为“太空飞船”运…

洛谷——P1983 [NOIP2013 普及组] 车站分级(拓扑排序、c++)

文章目录 一、题目[NOIP2013 普及组] 车站分级题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 二、题解基本思路&#xff1a;代码 一、题目 [NOIP2013 普及组] 车站分级 题目背景 NOIP2013 普及组 T4 题目描述 一条单…

imgaug库指南(五):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

算法每日一题:统计重复个数 | 字符串

大家好&#xff0c;我是星恒 感觉好难呀呀呀&#xff01;今天是一道困难题目&#xff0c;思路挺简单&#xff0c;但是有些细节点不是很容易想通&#xff0c;建议大家多画图试一试&#xff0c;这样就会好理解许多 题目&#xff1a;leetcode 466定义 str [s, n] 表示 str 由 n 个…