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

文章目录

    • 原理
      • 选举机制(重点)
        • 情况1:正常启动集群
        • 情况2:集群启动完,中途有机器挂了
      • 监听器
      • 客户端向服务端写入数据
        • 客户端向服务端Leader节点写入
        • 客户端向服务端Follower节点写入
      • Paxos算法(每个节点都可以提议者)
      • ZAB协议算法 - Paxos算法的改良 - 集群仅能一位提议者(即Leader)
        • 认识
        • 崩溃恢复
          • Leader挂,重新选举
          • 数据恢复
      • CAP理伦
    • 脚本
      • 集群统一启动、关闭、状态查看脚本
    • 源码分析(粗略)
      • 辅助源码
        • 持久化
        • 序列化
      • 服务端启动流程
      • 服务端选举Leader流程
      • Leader、Follower数据同步流程
      • 服务端Leader启动Zk过程
      • 服务端Follower启动Zk过程
      • 客户端连接Zk服务端过程

原理

选举机制(重点)

情况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@目标机器IPfor currentHostName in 192.168.19.107 192.168.19.108 192.168.19.109
doecho "=================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"}esacdone

在这里插入图片描述

源码分析(粗略)

辅助源码

持久化

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

接口: 快照【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

在这里插入图片描述


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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编码规则转换

思考: 如何将一个机内码转换为区内码? 只要将机内码减去 A0A0 就可以啦 如果只让我们用加法器来解决呢? 注意我们的数据占用了 32 位,如果想用补码进行减法运算的话,符号位怎么办??&#xf…

alibabacloud学习笔记07(小滴课堂)

讲解Sentinel自定义异常降级-新旧版本差异 讲解新版Sentinel自定义异常数据开发实战 如果我们都使用原生的报错,我们就无法得到具体的报错信息。 所以我们要自定义异常返回的数据提示: 实现BlockExceptionHandler并且重写handle方法: 使用F…

[网鼎杯 2020 半决赛]AliceWebsite --不会编程的崽

网鼎杯某些题还是很简单嘛,比如这题 有交互界面先去交互看看 斯,actionabout.php?有一种可能是存在任意文件读取,试一下/etc/passwd 看来猜想正确,直接读取根目录的flag

Linux下进程相关概念详解

目录 一、操作系统 概念 设计操作系统的目的 定位 如何理解“管理” 系统调用和库函数概念 二、进程 概念 描述进程—PCB(process control block) 查看进程 进程状态 进程优先级 三、其它的进程概念 一、操作系统 概念 任何计算机系统都包…

electron nsis 安装包 window下任务栏无法正常固定与取消固定 Pin to taskbar

问题 win10系统下,程序任务栏在固定后取消固定,展示的程序内容异常。 排查 1.通过论坛查询,应该是与app的api setAppUserModelId 相关 https://github.com/electron/electron/issues/3303 2.electron-builder脚本 electron-builder…

Ubuntu22.04下在Spark2.4.0中采用Local模式配置并启动pyspark

目录 一、前言 二、版本信息 三、配置相关文件 1.修改spark-env.sh文件 2.修改.bashrc文件 四、安装Python3.5.2并更改默认Python版本 1.查看当前默认Python版本 2.安装Python3.5.2 2.1 下载Python源码 2.2 解压源码 2.3 配置安装路径 2.4 编译和安装 2.5 验证安装…

线性dp:P2679 子串

1.P2679 子串 传送门https://www.luogu.com.cn/problem/P2679这道题是公共子串问题的变种,但是我第一时间确实没想到转移方程(写少了) 一开始看了题解也没太看懂,直到自己模拟一遍(模拟数据便于理解原理)…

从硬件角度看Linux的内存管理

1. 分页机制 分段机制的地址映射颗粒度太大,以整个进程地址空间为单位的分配方式导致内存利用率不高。 分页机制把这个分配机制的单位继续细化为固定大小的页(Page),进程的虚拟地址空间也按照页来分割,这样常用的数据和代码就可以以页为单位…

VLAN实验报告

实验要求: 实验参考图: 实验过程: r1: [r1]int g 0/0/0.1 [r1-GigabitEthernet0/0/0.1]ip address 192.168.1.1 24 [r1-GigabitEthernet0/0/0.1]dot1q termination vid 2 [r1-GigabitEthernet0/0/0.1]arp broadcast enable [r1]int g 0/0/…

131. 分割回文串(力扣LeetCode)

文章目录 131. 分割回文串题目描述回溯代码 131. 分割回文串 题目描述 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1: 输入&#xf…

#WEB前端(DIV、SPAN)

1.实验&#xff1a;DIV、SPAN 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; 类? 4.代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdev…

详细讲解Docker架构的原理、功能以及如何使用

一、简介 1、了解docker的前生LXC LXC为Linux Container的简写。可以提供轻量级的虚拟化&#xff0c;以便隔离进程和资源&#xff0c;而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中&…