Zookeeper学习2:原理、常用脚本、选举机制、监听器

发布于:2024-03-03 ⋅ 阅读:(59) ⋅ 点赞:(0)

原理

选举机制(重点)

情况1:正常启动集群

集群正常总固定票数: conf/zoo.cfg里面的server.的配置行数

特点:

  1. 一旦选举出领导leader,除非作为leader的zookeeper挂了,否则不会在重新选举,其他新进的zookeeper集群都作为追随者Following
  2. 存活的zookeeper机器必须【集群正常总固定票数】的一半以上才会进行选举leader角色,否则一直是Looking
  3. zookeeper可以给自己投票,一旦每个人的票数都一样,交换myid查看后,谁大就把投自己的票改投成myid最大的那个

在这里插入图片描述

集群中5台zookeeper机器依次启动后选举领导的整个过程
在这里插入图片描述

情况2:集群启动完,中途有机器挂了
触发选举条件【满足其一】
1. 有新zookeeper服务器启动加入
2. 中途在集群中的有zookeeper机器断联
选举过程情景
1. 集群中的Leader没挂,维持现状,依然是Leader机器为Leader
2. 集群中的Leader挂了,Leader选举规则:谁任期Epoch大选谁、任期一致,谁事务ID修改次数大就选谁、事务ID也一致,谁身份证号大就选谁

监听器

流程: zookeeper客户端告知服务端需要监听某某节点的数据变化,服务端一旦节点发生变化,就将变化通知内容推送给客户端


在这里插入图片描述

1. 首先要有一个main线程
2. 在main线程中创建Zookeeper客户端,这时就会创建两个线 程,一个负责网络连接通信(connet)),一个负责监听(listener)
3. 通过connectz线程将注册的监听事件发送给Zookeeper服务端
4. 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中
5. Zookeeper服务端监听到有数据或路径变化,就会将这个消息发送给Zookeeper客户端的listener线程
6. listener线程内部调用了process0方法,处理后续业务逻辑
常见的监听事件
1. 监听数据的变化 == get 节点 -w
2. 监听子节点增删的变化 == ls 节点 -w

监听数据的变化
在这里插入图片描述

监听子节点增删的变化
在这里插入图片描述

客户端向服务端写入数据

客户端向服务端Leader节点写入

流程: Leader会传递给Follower去写入,如果 超半数的zookeeper都写入成功,则Leader服务端机器会告诉客户端数据写入成功 ,剩下Follower还未写入的Leader会慢慢通知他们写入,反正最终zookeeper服务端集群内所有机器都写入成功

在这里插入图片描述

客户端向服务端Follower节点写入

流程: Follower会先将 客户端的写入请求转给Leader,Leader自己将写入请求先执行,在将这个写入请求分发给集群内所有Follower机器 ,所有集群中超过半数的zookeeper都写入成功,则Leader会告知当初最开始那台Follower机器说明此次写入成功,然后由该台Follower告知客户端集群此次写入成功

在这里插入图片描述

Paxos算法(每个节点都可以提议者)

Paxos算法: 基于消息传递且具有高度容错特性的一致性算法。快速正确的在一个分布式系统保持数据值一致,保证无论发生任何异常都不会破坏系统的一致性

Propose(提议): 任务编号

Proposal(提案): 任务编号+任务内容

Paxos角色==Zookeeper系统中所有节点==节点可以拥有多角色
提议者(proposer)
接受者(acceptor)
学习者(learner)
Paxos主要阶段
准备阶段:提议者向接受者发送一个提议编号,接受者如果收到的提议编号比自己已经接受的提议编号大,接受该提议,并返回自己已经接受的提议编号和值
提议阶段:提议者收到了大多数接受者的接受,提议者向所有接受者发送一个提议,包括提议编号和值。
学习阶段:一旦某值被大多数接受者接受,学习者就可以学习到这个值并应用到系统中
接受者收到提案者空白提案请求时的原则
不在接受提案ID小于等于当前收到的
不在接受提案落档中提案ID小于当前的
不违背以前做出的承诺

在这里插入图片描述


Paxos算法完美情况
在这里插入图片描述


Paxos算法弊端
在这里插入图片描述

ZAB协议算法 - Paxos算法的改良 - 集群仅能一位提议者(即Leader)

认识

概念: 只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader客户端将数据同步到其他Follower节点。即Zookeeper只有一个Leader可以发起提案

ZAB模式
消息广播
崩溃恢复
ZAB针对事务处理过程(两阶段)
广播事务阶段
广播事务提交操作
1. 客户端发起一个写操作请求
2. Leader服务器将客户端的请求转化为事务Proposal提案,同时为每个Proposal分配一个全局的ID,即zxid
3. Leader服务器为每个Follower服务器分配一个单独的队列,然后将需要广播的Proposal依次放到队列中去,并且根据FIFO策略进行消息发送
4. Follower接收到Proposal后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后向Leader反馈一个Ack响应消息
5. Leader接收到超过半数以上Follower的Ack响应消息后,即认为消息发送成功,可以发送commit消息
6. Leaderl向所有Follower广播commit消息,同时自身也会完成事务提交。Follower接收到commit消息后,会将上一条事务提交

此图对应的是上图的流程图
在这里插入图片描述

崩溃恢复
Zab协议崩溃恢复同时满足的要求
1. 已经产生提交(Proposal)的提案(过半数都Ack),Follower必须执行
2. 未提交的提案直接丢弃 - 未proposal给follower的提案
Leader挂,重新选举
新Leader满足要求
1. 新Leader必须都是己经提交了Proposall的Follower服务器节点
2. 新选举的Leader节点中含有最大的zxid)这样做的好处是可以避免Leader服务器检查Proposal的提交和丢弃工作
数据恢复
数据恢复
新Leader选举
开始接收客户端请求前,首先确认事务日志的所有过半同意的提案已经commit
某个Follower同步完成Leader的提案后,才会将其加入到真正可用的Follower列表中

CAP理伦

分布式系统最多同时满足CAP其中的两项,不可能三项同时满足

Zookeeper:满足的是CP的两项要求

CAP
一致性(Consistency):集群之间的数据保持一致
可用性(Available):系统服务一直可用,且保证用户每个操作能在有限时间返回结果
分区容错性(Partition Tolerance):遇到网络分区故障,仍然能对外提供可用服务
为什么Zookeeper不满足A
极端情况下,服务端会丢弃一些客户端请求
进行Leader选举时,集群不可用

脚本

集群统一启动、关闭、状态查看脚本

zk.sh

#!/bin/bash
# 运行此脚本前必须把当前机器人的公私密钥给到目标运行机器 == 要不然每次运行此脚本时都会叫你输入每台目标机器的密码
# 命令1(本机生成RSA公私密钥):ssh-keygen -t rsa
# 命令2(将密钥传给目标三台机器即192.168.19.107、192.168.19.108、192.168.19.109 ):ssh-copy-id root@目标机器IP




for currentHostName in 192.168.19.107 192.168.19.108 192.168.19.109
do
	echo "=================zookeeper【${currentHostName}】【$1】==============================="
	case $1 in
	"start") {
	  ssh $currentHostName "cd /opt/module/zookeeper-3.9.1 && sh bin/zkServer.sh start"
	}
	;;


	"stop") {
	  ssh $currentHostName "cd /opt/module/zookeeper-3.9.1 && sh bin/zkServer.sh stop"
	}
	;;

	"status") {
	  ssh $currentHostName "cd /opt/module/zookeeper-3.9.1 && sh bin/zkServer.sh status"
	}
	;;

	*) {
	  echo "未知命令,仅支持start|stop|status"
	}

	esac


done

在这里插入图片描述

源码分析(粗略)

辅助源码

持久化

数据存储: 集群中的数据会在内存(树)、磁盘中各存一份

接口: 快照【org.apache.zookeeper.server.persistence.SnapShot】、事务记录【org.apache.zookeeper.server.persistence.TxnLog】

事务日志(txnlog): ZooKeeper会将所有的写操作以事务的形式记录在事务日志中,这些写操作包括创建节点、更新节点数据、删除节点等。事务日志是一个追加写的日志文件,用于记录每个写操作的详细信息。通过事务日志,ZooKeeper可以保证数据的一致性和持久性

快照(snapshot): ZooKeeper定期会生成一个快照文件,用于保存当前内存中所有节点的状态。快照文件包含了所有节点的数据和元数据信息。当ZooKeeper服务器启动时,会首先加载最新的快照文件,然后通过回放事务日志来恢复到最新的状态。

Zookeeper启动数据恢复流程: 先加载最新的快照文件,然后通过回放事务日志来将数据恢复到最新的状态

在这里插入图片描述

序列化

接口: 序列化、反序列化【org.apache.jute.Record】

在这里插入图片描述

服务端启动流程

入口类: org.apache.zookeeper.server.quorum.QuorumPeerMain#main

在这里插入图片描述

服务端选举Leader流程

在这里插入图片描述

Leader、Follower数据同步流程

概括: Follower必须去看Leader保持一致,而不是Leader跟Follower保持一致

【Follower】Learner: org.apache.zookeeper.server.quorum.Learner#registerWithLeader

【Leader】LearnerHandler: org.apache.zookeeper.server.quorum.LearnerHandler#run

差异化同步
回滚同步
提交同步
全量同步
同步方式
Diff:Leader、Follower都一样,无需任何操作
Trunc Follower:Follower的事务ID比Leader大,则Follower回滚成跟Leader一致
Commit:Leader的事务ID比Follower大,则Leader同步提案给Follower执行成一致
Follower没任何数据:则Leader以Snap方式同步执行恢复给Follower

在这里插入图片描述

服务端Leader启动Zk过程

核心: org.apache.zookeeper.server.quorum.Leader#startZkServer

在这里插入图片描述

服务端Follower启动Zk过程

核心: org.apache.zookeeper.server.quorum.Follower#followLeader

在这里插入图片描述

客户端连接Zk服务端过程

核心入口: org.apache.zookeeper.ZooKeeperMain#main

在这里插入图片描述


刚兴趣的同行可以进群沟通交流,内置机器人供大家愉快

在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到