ZooKeeper分布式协调框架

news/2025/3/4 23:19:16/

ZooKeeper分布式协调框架

在这里插入图片描述

  1. 学会ZooKeeper的基本使用:命令行、Java编程
  2. 理解ZooKeeper watcher监听器工作原理:注册、监听事件、回调函数(考点)
  3. 能独立描述出ZooKeeper选举过程(难点、考点)
  4. 理解、并讲述客户端从ZooKeeper读写的过程(考点)

1. 为什么要用ZooKeeper

  • 分布式框架多个独立的程序协同工作比较复杂
    • 开发人员容易花较多的精力实现如何使多个程序协同工作的逻辑
    • 导致没有时间更好的思考实现程序本身的逻辑
    • 或者开发人员对程序间的协同工作关注不够,造成协调问题
    • 且这个分布式框架中协同工作的逻辑是共性的需求
  • ZooKeeper简单易用,能够很好的解决分布式框架在运行中,出现的各种协调问题。比如集群master主备切换、节点的上下线感知、统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等等

2. 什么是ZooKeeper?

  • 是Google的Chubby的一个开源实现版
  • ZooKeeper
    • 一个分布式的,开源的,用于分布式应用程序的协调服务(service)
    • 主从架构
  • Zookeeper 作为一个分布式的服务框架
    • 主要用来解决分布式集群中应用系统的一致性问题
    • 它能提供基于类似于文件系统的目录节点树方式的数据存储,
    • Zookeeper 作用主要是用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理

在这里插入图片描述

3. ZooKeeper应用初体验

从下图观察:ZooKeeper集群目前有两种角色:leader、follower;

ZooKeeper集群也是主从架构的:leader为主;follower为从

在这里插入图片描述

通过客户端操作ZooKeeper集群,有两种类型的客户端

①命令行zkCli

②Java编程

3.1 zkCli命令行

  • 集群命令(每个节点运行此命令

在这里插入图片描述

# 启动ZooKeeper集群;在ZooKeeper集群中的每个节点执行此命令
${ZK_HOME}/bin/zkServer.sh start
# 停止ZooKeeper集群(每个节点执行以下命令)
${ZK_HOME}/bin/zkServer.sh stop
# 查看集群状态(每个节点执行此命令)
${ZK_HOME}/bin/zkServer.sh status
  • 客户端连接zkServer服务器

在这里插入图片描述

# 使用ZooKeeper自带的脚本,连接ZooKeeper的服务器
zkCli.sh -server node01:2181,node02:2181,node03:2181

-server选项后指定参数node01:2181,node02:2181,node03:2181

客户端随机的连接三个服务器中的一个

  • 客户端发出对ZooKeeper集群的读写请求

    • ZooKeeper集群中有类似于linux文件系统的一个简版的文件系统;目录结构也是树状结构(目录树)

在这里插入图片描述

  • 重要技巧:不会就喊help

  • 还记得其它组件中help的使用吗?

在这里插入图片描述

  • 常用命令
#查看ZooKeeper根目录/下的文件列表
ls /

在这里插入图片描述

#创建节点,并指定数据
create /kkb	kkb
#获得某节点的数据
get /kkb

在这里插入图片描述

#修改节点的数据
set /kkb kkb01#删除节点
delete /kkb

3.2 Java API编程—Curator(重点)

IDE可以是eclipse,或IDEA;此处以IDEA演示

编程分两类:原生API编程;curator编程

  • Curator官网
  • Curator编程
    • Curator对ZooKeeper的api做了封装,提供简单易用的api;
    • 它的风格是Curator链式编程

4.基本概念和操作

分布式通信有几种方式

1、直接通过网络连接的方式进行通信;

2、通过共享存储的方式,来进行通信或数据的传输

ZooKeeper使用第二种方式,提供分布式协调服务

4.1 ZooKeeper数据结构

ZooKeeper主要由以下三个部分实现

ZooKeeper=①简版文件系统(Znode)+②原语+③通知机制(Watcher)。

  • ZK文件系统
    • 基于类似于文件系统的目录节点树方式的数据存储
  • 原语
    • 可简单理解成ZooKeeper的基本的命令
  • Watcher(监听器)

在这里插入图片描述
在这里插入图片描述

4.2 数据节点ZNode

4.2.1 什么是ZNode

  • ZNode 分为四类:
持久节点临时节点
非有序节点createcreate -e
有序节点create -screate -s -e

4.2.2 持久节点

  • 类比,文件夹
# 创建节点/zk_test,并设置数据my_data
create /zk_test my_data
# 持久节点,只有显示的调用命令,才能删除永久节点
delete /zk_test

4.2.3 临时节点

  • 临时节点的生命周期跟客户端会话session绑定,一旦会话失效,临时节点被删除。
# client1上创建临时节点
create -e /tmp tmpdata# client2上查看client1创建的临时节点
ls /# client1断开连接
close# client2上观察现象,发现临时节点被自动删除
ls /

4.2.4 有序节点

  • ZNode也可以设置为有序节点

  • 为什么设计临时节点?

  • 防止多个不同的客户端在同一目录下,创建同名ZNode,由于重名,导致创建失败

  • 如何创建临时节点

    • 命令行使用-s选项:create -s /kkb kkb

    • Curator编程,可添加一个特殊的属性:CreateMode.EPHEMERAL

      在这里插入图片描述

  • 一旦节点被标记上这个属性,那么在这个节点被创建时,ZooKeeper 就会自动在其节点后面追加上一个整型数字

    • 这个整数是一个由父节点维护的自增数字。
    • 提供了创建唯一名字的ZNode的方式
    # 创建持久、有序节点
    create -s /test01 test01-data
    # Created /test010000000009
    

4.3 会话(Session)

在这里插入图片描述

4.4.1 什么是会话

  • 客户端要对ZooKeeper集群进行读写操作,得先与某一ZooKeeper服务器建立TCP长连接;此TCP长连接称为建立一个会话Session。

  • 每个会话有超时时间:SessionTimeout

    • 当客户端与集群建立会话后,如果超过SessionTimeout时间,两者间没有通信,会话超时

4.4.2 会话的特点

  • 客户端打开一个Session中的请求以FIFO(先进先出)的顺序执行;
    • 如客户端client01与集群建立会话后,先发出一个create请求,再发出一个get请求;
    • 那么在执行时,会先执行create,再执行get
  • 若打开两个Session,无法保证Session间,请求FIFO执行;只能保证一个session中请求的FIFO

4.4.3 会话的生命周期

在这里插入图片描述

  • 会话的生命周期
    • 未建立连接
    • 正在连接
    • 已连接
    • 关闭连接

4.4 请求

  • 读写请求
    • 通过客户端向ZooKeeper集群中写数据
    • 通过客户端从ZooKeeper集群中读数据

在这里插入图片描述

4.5 事务zxid

  • 事务

    • 客户端的写请求,会对ZooKeeper中的数据做出更改;如增删改的操作
    • 每次写请求,会生成一次事务
    • 每个事务有一个全局唯一的事务ID,用 ZXID 表示;全局自增
  • 事务特点

    • ACID:
    • 原子性atomicity | 一致性consistency | 隔离性isolation | 持久性durability
  • ZXID结构:

    • 通常是一个64位的数字。由epoch+counter组成
    • epoch、counter各32位
      在这里插入图片描述

4.6 Watcher监视与通知

4.6.1 为什么要有Watcher

  • 问:客户端如何获取ZooKeeper服务器上的最新数据?

    • 方式一轮询:ZooKeeper以远程服务的方式,被客户端访问;客户端以轮询的方式获得znode数据,效率会比较低(代价比较大)

    在这里插入图片描述

    • 方式二基于通知的机制:
      • 客户端在znode上注册一个Watcher监视器
      • 当znode上数据出现变化,watcher监测到此变化,通知客户端

    在这里插入图片描述

  • 对比,那种好?

4.6.2 什么是Watcher?

  • 客户端在服务器端,注册的事件监听器;
  • watcher用于监听znode上的某些事件
    • 比如znode数据修改、节点增删等;
    • 当监听到事件后,watcher会触发通知客户端

4.6.3 如何设置Watcher

注意:Watcher是一个单次触发的操作

  • 可以设置watcher的命令如下:
    在这里插入图片描述

  • 示例1

#ls path [watch]
#node01 上执行
ls /zk_test watch#node02 上执行
create /zk_test/dir01 dir01-data#观察node-01上变化
[zk: node-01:2181,node-02:2181,node-03:2181(CONNECTED) 87] 
WATCHER::WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/zk_test

图示:

  • client1上执行步骤1

  • client2上执行步骤2;

  • client1上观察现象3

在这里插入图片描述
在这里插入图片描述

  • 示例2
#监控节点数据的变化;
#node02上
get /zk_test watch#node03上
set /zk_test "junk01"
#观察node2上cli的输出,检测到变化
  • 示例3:节点上下线监控

    • 原理:

      1. 节点1(client1)创建临时节点
      2. 节点2(client2)在临时节点,注册监听器watcher
      3. 当client1与zk集群断开连接,临时节点会被删除
      4. watcher发送消息,通知client2,临时节点被删除的事件
    • 用到的zk特性:

      ​ Watcher+临时节点

    • 好处:

      ​ 通过这种方式,检测和被检测系统不需要直接关联(如client1与client2),而是通过ZK上的某个节点进行关联,大大减少了系统耦合

    • 实现:

      client1操作

      # 创建临时节点
      create -e /zk_tmp tmp-data
      

      client2操作

      # 在/zk_tmp注册监听器
      ls /zk_tmp watch
      

      client1操作

      # 模拟节点下线
      close
      

      观察client2

      WATCHER::WatchedEvent state:SyncConnected type:NodeDeleted path:/zk_tmp
      
    • 图示:

      client1:

      在这里插入图片描述

      client2:
      在这里插入图片描述

4.7 总结

5. ZooKeeper工作原理

  • ZooKeeper使用原子广播协议叫做Zab(ZooKeeper Automic Broadcast)协议
  • Zab协议有两种模式
    • 恢复模式(选主):因为ZooKeeper也是主从架构;当ZooKeeper集群没有主的角色leader时,从众多服务器中选举leader时,处于此模式
    • 广播模式(同步):当集群有了leader后,客户端向ZooKeeper集群读写数据时,集群处于此模式
  • 为了保证事务的顺序一致性,ZooKeeper采用了递增的事务id号(zxid)来标识事务,所有提议(proposal)都有zxid

6. ZooKeeper应用场景

  • ZooKeeper应用场景
    在这里插入图片描述
  1. NameNode使用ZooKeeper实现高可用.
  2. Yarn ResourceManager使用ZooKeeper实现高可用.
  3. 利用ZooKeeper对HBase集群做高可用配置
  4. kafka使用ZooKeeper
    • 保存消息消费信息比如offset.
    • 用于检测崩溃
    • 主题topic发现
    • 保持主题的生产和消费状态

7. 访问控制ACL(ACL访问控制列表)

7.0 何为ACL

ACL(Access Control List)可以设置某些客户端,对zookeeper服务器上节点的权限,如增删改查等

7.1 为什么要用ACL

zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题

7.2 ACL种类

ZooKeeper 采用 ACL(Access Control Lists)策略来进行权限控制。ZooKeeper 定义了如下5种权限。

  • CREATE: 创建子节点的权限。

  • READ: 获取节点数据和子节点列表的权限。

  • WRITE:更新节点数据的权限。

  • DELETE: 删除子节点的权限。

  • ADMIN: 设置节点ACL的权限。

注意:CREATE 和 DELETE 都是针对子节点的权限控制。

7.3 如何设置ACL

  1. 五种权限简称
  • CREATE -> 增 -> c
  • READ -> 查 -> r
  • WRITE -> 改 -> w
  • DELETE -> 删 -> d
  • ADMIN -> 管理 -> a
  • 这5种权限简写为crwda
  1. 鉴权模式
  • world:默认方式,相当于全世界都能访问
  • auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
  • digest:即用户名:密码这种方式认证,这也是业务系统中最常用的
  • ip:使用Ip地址认证
  1. 演示auth方式
# 1)增加一个认证用户
# addauth digest 用户名:密码明文
addauth digest kkb:kkb# 2)设置权限
# setAcl /path auth:用户名:密码明文:权限
setAcl /zk_test auth:kkb:kkb:rw# 3)查看ACL设置
getAcl /zk_test

在这里插入图片描述

  1. 问:如何解释下图命令的执行效果? 在这里插入图片描述

8. HDFS HA方案

8.1 ZooKeeper监听器

  • 关于ZooKeeper监听器有三个重要的逻辑:

    • 注册:客户端向ZooKeeper集群注册监听器

    • 监听事件:监听器负责监听特定的事件

    • 回调函数:当监听器监听到事件的发生后,调用注册监听器时定义的回调函数

8.2 类比举例

  • 为了便于理解,举例:旅客住店无房可住的情况

    • 一哥们去酒店办理入住,但是被告知目前无空房
    • 这哥们告诉客服:你给我记住了,帮我留意一下有没有空出的房间,如果有,及时通知我(类似注册监听器,监听特定事件
    • 将近12点,有房客退房,有空闲的房间(事件
    • 客服发现有空房(监听到事件
    • 及时通知这哥们
    • 这哥们收到通知后,做一些事,比如马上从附近酒吧赶回酒店(调用回调函数

    在这里插入图片描述

8.3 HDFS HA原理(难点)

关键逻辑:

①监听器:注册、监听事件、回调函数

②共享存储:JournalNode
在这里插入图片描述

  • 在Hadoop 1.x版本,HDFS集群的NameNode一直存在单点故障问题:

    • 集群只存在一个NameNode节点,它维护了HDFS所有的元数据信息
    • 当该节点所在服务器宕机或者服务不可用,整个HDFS集群处于不可用状态
  • Hadoop 2.x版本提出了高可用 (High Availability, HA) 解决方案

HDFS HA方案,主要分两部分:

①元数据同步

②主备切换

  • ①元数据同步

    • 在同一个HDFS集群,运行两个互为主备的NameNode节点。
    • 一台为主Namenode节点,处于Active状态,一台为备NameNode节点,处于Standby状态。
    • 其中只有Active NameNode对外提供读写服务,Standby NameNode会根据Active NameNode的状态变化,在必要时切换成Active状态。
    • JournalNode集群
      • 在主备切换过程中,新的Active NameNode必须确保与原Active NamNode元数据同步完成,才能对外提供服务
      • 所以用JournalNode集群作为共享存储系统;
      • 当客户端对HDFS做操作,会在Active NameNode中edits.log文件中作日志记录,同时日志记录也会写入JournalNode集群;负责存储HDFS新产生的元数据
      • 当有新数据写入JournalNode集群时,Standby NameNode能监听到此情况,将新数据同步过来
      • Active NameNode(写入)和Standby NameNode(读取)实现元数据同步
      • 另外,所有datanode会向两个主备namenode做block report

在这里插入图片描述

  • ②主备切换

  • ZKFC涉及角色

    • 每个NameNode节点上各有一个ZKFC进程
    • ZKFC即ZKFailoverController,作为独立进程存在,负责控制NameNode的主备切换
    • ZKFC会监控NameNode的健康状况,当发现Active NameNode异常时,通过Zookeeper集群进行namenode主备选举,完成Active和Standby状态的切换
      • ZKFC在启动时,同时会初始化HealthMonitor和ActiveStandbyElector服务
      • ZKFC同时会向HealthMonitor和ActiveStandbyElector注册相应的回调方法(如上图的①回调、②回调)
      • HealthMonitor定时调用NameNode的HAServiceProtocol RPC接口(monitorHealth和getServiceStatus),监控NameNode的健康状态并向ZKFC反馈
      • ActiveStandbyElector接收ZKFC的选举请求,通过Zookeeper自动完成namenode主备选举
      • 选举完成后回调ZKFC的主备切换方法对NameNode进行Active和Standby状态的切换
  • **主备选举过程:**两个ZKFC通过各自ActiveStandbyElector发起NameNode的主备选举,这个过程利用Zookeeper的写一致性和临时节点机制实现

    • 当发起一次主备选举时,ActiveStandbyElector会尝试在Zookeeper创建临时节点/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock,Zookeeper的写一致性保证最终只会有一个ActiveStandbyElector创建成功
  • ActiveStandbyElector从ZooKeeper获得选举结果

    • 创建成功的 ActiveStandbyElector回调ZKFC的回调方法②,将对应的NameNode切换为Active NameNode状态
  • 而创建失败的ActiveStandbyElector回调ZKFC的回调方法②,将对应的NameNode切换为Standby NameNode状态

  • 不管是否选举成功,所有ActiveStandbyElector都会在临时节点ActiveStandbyElectorLock上注册一个Watcher监听器,来监听这个节点的状态变化事件

    • 如果Active NameNode对应的HealthMonitor检测到NameNode状态异常时,通知对应ZKFC
  • ZKFC会调用 ActiveStandbyElector 方法,删除在Zookeeper上创建的临时节点ActiveStandbyElectorLock

    • 此时,Standby NameNode的ActiveStandbyElector注册的Watcher就会监听到此节点的 NodeDeleted事件。
  • 收到这个事件后,此ActiveStandbyElector发起主备选举,成功创建临时节点ActiveStandbyElectorLock,如果创建成功,则Standby NameNode被选举为Active NameNode(过程同上)

  • 如何防止脑裂

    • 脑裂

      分布式系统中双主现象又称为脑裂,由于Zookeeper的“假死”、长时间的垃圾回收或其它原因都可能导致双Active NameNode现象,此时两个NameNode都可以对外提供服务,无法保证数据一致性

    • 隔离

      对于生产环境,这种情况的出现是毁灭性的,必须通过自带的**隔离(Fencing)**机制预防此类情况

    • 原理

      • ActiveStandbyElector成功创建ActiveStandbyElectorLock临时节点后,会创建另一个ActiveBreadCrumb持久节点

      • ActiveBreadCrumb持久节点保存了Active NameNode的地址信息

      • 当Active NameNode在正常的状态下断开Zookeeper Session,会一并删除临时节点ActiveStandbyElectorLock、持久节点ActiveBreadCrumb

      • 但是如果ActiveStandbyElector在异常的状态下关闭Zookeeper Session,那么持久节点ActiveBreadCrumb会保留下来(此时有可能由于active NameNode与ZooKeeper通信不畅导致,所以此NameNode还处于active状态

      • 当另一个NameNode要由standy变成active状态时,会发现上一个Active NameNode遗留下来的ActiveBreadCrumb节点,那么会回调ZKFailoverController的方法对旧的Active NameNode进行fencing

        ①首先ZKFC会尝试调用旧Active NameNode的HAServiceProtocol RPC接口的transitionToStandby方法,看能否将其状态切换为Standby

        ②如果transitionToStandby方法切换状态失败,那么就需要执行Hadoop自带的隔离措施,Hadoop目前主要提供两种隔离措施:
        sshfence:SSH to the Active NameNode and kill the process;
        shellfence:run an arbitrary shell command to fence the Active NameNode

        ③只有成功地fencing之后,选主成功的ActiveStandbyElector才会回调ZKFC的becomeActive方法将对应的NameNode切换为Active,开始对外提供服务

前情回顾:

  • ZooKeeper使用原子广播协议Zab(ZooKeeper Automic Broadcast),保证分布式一致性
  • 协议Zab协议有两种模式,它们分别是
  • 恢复模式(选主):因为ZooKeeper也是主从架构;当ZooKeeper集群没有主的角色leader时,从众多服务器中选举leader时,处于此模式;主要处理内部矛盾,我们称之为安其内
  • 广播模式(同步):当集群有了leader后,客户端向ZooKeeper集群读写数据时,集群处于此模式;主要处理外部矛盾,我们称之为攘其外
  • 事务
  • 为了保证事务的顺序一致性,ZooKeeper采用了递增的事务id号(zxid)来标识事务,所有提议(proposal)都有zxid
  • 每次事务的提交,必须符合quorum多数派

9. ZooKeeper之攘其外(重点)

9.1 ZooKeeper集群架构图

  • ZooKeeper集群也是主从架构
    • 主角色:leader
    • 从角色:follower或observer;统称为learner

在这里插入图片描述

客户端与ZK集群交互,主要分两大类操作

9.2 读操作

在这里插入图片描述

  • 常见的读取操作,如ls /查看目录;get /zktest查询ZNode数据

  • 读操作

    • 客户端先与某个ZK服务器建立Session

    • 然后,直接从此ZK服务器读取数据,并返回客户端即可

    • 关闭Session

9.3 写操作

  • 写操作比较复杂;为了便于理解,先举个生活中的例子:去银行存钱
    • 银行柜台共有5个桂圆姐姐,编程从①到⑤,其中③是领导leader
    • 有两个客户
    • 客户①找到桂圆①,说:昨天少给我存了1000万,现在需要给我加进去
    • 桂圆①说,对不起先生,我没有这么大的权限,请你稍等一下,我向领导leader③汇报一下
    • 领导③收到消息后,为了做出英明的决策,要征询下属的意见(proposal)①②④⑤
    • 只要有过半数quorum(5/2+1=3,包括leader自己)同意,则leader做出决定(commit),同意此事
    • leader告知所有下属follower,你们都记下此事生效
    • 柜员①答复客户①,说已经给您账号里加了1000万

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 客户端写操作

    • ①客户端向zk集群写入数据,如create /kkb;与一个follower建立Session连接,从节点follower01

    • ②follower将写请求转发给leader

    • ③leader收到消息后,发出proposal提案(创建/kkb),每个follower先记录下要创建/kkb

    • ④超过半数quorum(包括leader自己)同意提案,则leader提交commit提案,leader本地创建/kkb节点ZNode

    • ⑤leader通知所有follower,也commit提案;follower各自在本地创建/kkb

    • ⑥follower01响应client

10. ZooKeeper之安其内(重点)

10.1 架构问题

在这里插入图片描述

  • leader很重要?

  • 如果没有leader怎么办?

    • 开始选举新的leader
  • ZooKeeper服务器四种状态:

    • looking:服务器处于寻找Leader群首的状态

    • leading:服务器作为群首时的状态

    • following:服务器作为follower跟随者时的状态

    • observing:服务器作为观察者时的状态

leader选举分两种情况

  • 全新集群leader选举

  • 非全新集群leader选举

10.2 全新集群leader选举

在这里插入图片描述

  • 以3台机器组成的ZooKeeper集群为例

  • 原则:集群中过半数(多数派quorum)Server启动后,才能选举出Leader;

    • 此处quorum数是多少?3/2+1=2
    • 即quorum=集群服务器数除以2,再加1
  • 理解leader选举前,先了解几个概念

    • 选举过程中,每个server需发出投票;投票信息vote信息结构为(sid, zxid)

      全新集群,server1~3初始投票信息分别为:

      ​ server1 -> (1, 0)
      ​ ​server2 -> (2, 0)
      ​ server3 -> (3, 0)

    • leader选举公式

      ​ server1 vote信息 (sid1,zxid1)

      ​ server2 vote信息 (sid2,zxid2)

      ①zxid大的server胜出;

      ②若zxid相等,再根据判断sid判断,sid大的胜出

  • 选举leader流程:

    假设按照ZK1、ZK2、ZK3的依次启动

    • 启动ZK1后,投票给自己,vote信息(1,0),没有过半数,选举不出leader

    • 再启动ZK2;ZK1和ZK2票投给自己及其他服务器;ZK1的投票为(1, 0),ZK2的投票为(2, 0)

    • 处理投票。每个server将收到的多个投票做处理

      • 如ZK1投给自己的票(1,0)与ZK2传过来的票(2,0)比较;
      • 利用leader选举公式,因为zxid都为0,相等;所以判断sid最大值;2>1;ZK1更新自己的投票为(2, 0)
      • ZK2也是如此逻辑,ZK2更新自己的投票为(2,0)
    • 再次发起投票

      • ZK1、ZK2上的投票都是(2,0)
      • 发起投票后,ZK1上有一个自己的票(2,0)和一票来自ZK2的票(2,0),这两票都选ZK2为leader
      • ZK2上有一个自己的票(2,0)和一票来自ZK1的票(2,0),这两票都选ZK2为leader
      • 统计投票。server统计投票信息,是否有半数server投同一个服务器为leader;
        • ZK2当选2票;多数
      • 改变服务器状态。确定Leader后,各服务器更新自己的状态
        • 更改ZK2状态从looking到leading,为Leader
        • 更改ZK1状态从looking到following,为Follower
    • 当K3启动时,发现已有Leader,不再选举,直接从LOOKING改为FOLLOWING

10.3 非全新集群leader选举

在这里插入图片描述

  • 选举原理同上比较zxid、sid
  • 不再赘述

11. ZAB算法(难点考点)

11.1 仲裁quorum

  • 什么是仲裁quorum?

    • 发起proposal时,只要多数派同意,即可生效
  • 为什么要仲裁?

    • 多数据派不需要所有的服务器都响应,proposal就能生效
    • 且能提高集群的响应速度
  • quorum数如何选择?

    • 集群节点数 / 2 + 1
    • 如3节点的集群:quorum数=3/2+1=2

11.2 网络分区、脑裂

  • 网络分区:网络通信故障,集群被分成了2部分

  • 脑裂:

    • 原leader处于一个分区;
    • 另外一个分区选举出新的leader
    • 集群出现2个leader

11.3 ZAB算法

raft算法动图地址

  • ZAB与RAFT相似,区别如下:

    1、zab心跳从follower到leader;raft相反

    2、zab任期叫epoch

  • 一下以RAFT算法动图为例,分析ZAB算法

在这里插入图片描述

在这里插入图片描述

11.4 ZooKeeper服务器个数

  • 仲裁模式下,服务器个数最好为奇数个。why?

在这里插入图片描述

  • 5节点的比6节点的集群
    • 容灾能力一样,
    • quorum小,响应快

12. ZooKeeper工作原理

12.1写操作流程图

在这里插入图片描述

  1. 在Client向Follwer发出一个写的请求
  2. Follwer把请求发送给Leader
  3. Leader接收到以后开始发起投票并通知Follwer进行投票
  4. Follwer把投票结果发送给Leader
  5. Leader将结果汇总,如果多数同意,则开始写入同时把写入操作通知给Follwer,然后commit
  6. Follwer把请求结果返回给Client

12.2 ZooKeeper状态同步

完成leader选举后,zk就进入ZooKeeper之间状态同步过程

  1. leader构建NEWLEADER封包,包含leader中最大的zxid值;广播给其它follower
  2. follower收到后,如果自己的最大zxid小于leader的,则需要与leader状态同步;否则不需要
  3. leader给需要同步的每个follower创建LearnerHandler线程,负责数据同步请求
  4. leader主线程等待LearnHandler线程处理结果
  5. 只有多数follower完成同步,leader才开始对外服务,响应写请求
  6. LearnerHandler线程处理逻辑
    1. 接收follower封包FOLLOWERINFO,包含此follower最大zxid(代称f-max-zxid)
    2. f-max-zxid与leader最大zxid(代称l-max-zxid)比较
    3. 若相等,说明当前follower是最新的
    4. 另外,若在判断期间,有没有新提交的proposal
      1. 如果有那么会发送DIFF封包将有差异的数据同步过去.同时将follower没有的数据逐个发送COMMIT封包给follower要求记录下来.
      2. 如果follower数据id更大,那么会发送TRUNC封包告知截除多余数据.
      3. 如果这一阶段内没有提交的提议值,直接发送SNAP封包将快照同步发送给follower.
    5. 以上消息完毕之后,发送UPTODATE封包告知follower当前数据就是最新的了
    6. 再次发送NEWLEADER封包宣称自己是leader,等待follower的响应.
      在这里插入图片描述

zookeeper_919">13.curator框架操作zookeeper

下载curator pom依赖
在这里插入图片描述

在这里插入图片描述

14.应用场景—分布式

在这里插入图片描述

create -s -e /locker/node_ ndata

15.扩展阅读

follower与leader状态同步

主备切换示例

在这里插入图片描述

在这里插入图片描述

  1. 假设五台ZooKeeper服务器,分别为zk1,zk2,zk3,zk4,zk5,sid分别为1、2、3、4、5,依次启动zk1,zk2,zk3,zk4,zk5。问哪台是leader,为什么这台是leader?
  2. 同一个客户端同时发起多次请求操作时ZooKeeper内部是如何操作的?多个客户端同时发起多个请求时又是如何操作的?

http://www.ppmy.cn/news/1576667.html

相关文章

【leetcode hot 100 76】最小覆盖子串

解法一&#xff1a;&#xff08;滑动窗口&#xff09;在 s 上滑动窗口&#xff0c;通过移动 r 指针不断扩张窗口。当窗口包含 t 全部所需的字符后&#xff0c;如果能收缩&#xff0c;我们就收缩窗口直到得到最小窗口。 class Solution {// <字母, 出现的次数>Map<Cha…

【实战篇】【深度解析DeepSeek:从机器学习到深度学习的全场景落地指南】

一、机器学习模型:DeepSeek的降维打击 1.1 监督学习与无监督学习的"左右互搏" 监督学习就像学霸刷题——给标注数据(参考答案)训练模型。DeepSeek在信贷风控场景中,用逻辑回归模型分析百万级用户数据,通过特征工程挖掘出"凌晨3点频繁申请贷款"这类魔…

广义线性模型下的数据分析(R语言)

一、实验目的&#xff1a; 通过上机试验&#xff0c;掌握利用R实现线性回归分析、逻辑回归、列联分析及方差分析&#xff0c;并能对分析结果进行解读。 数据&#xff1a; 链接: https://pan.baidu.com/s/1JqZ_KbZJEk-pqSUWKwOFEw 提取码: hxts 二、实验内容&#xff1a; 1、2…

Python PDF文件拆分-详解

目录 使用工具 将PDF按页数拆分 将PDF的每一页拆分为单独的文件 将PDF按指定页数拆分 根据页码范围拆分PDF 根据指定内容拆分PDF 将PDF的一页拆分为多页 在日常生活中&#xff0c;我们常常会遇到大型的PDF文件&#xff0c;这些文件可能难以发送、管理和查阅。将PDF拆分成…

【Java 基础(人话版)】Java 虚拟机(JVM)

引言 学习 Java 时&#xff0c;我们经常听到 “一次编译&#xff0c;随处运行” 这句话。这背后的核心支撑技术就是 Java 虚拟机&#xff08;JVM, Java Virtual Machine&#xff09;。JVM 负责运行 Java 代码&#xff0c;使得 Java 具有良好的跨平台能力。 但你知道吗&#x…

DeepSeek vs Grok vs ChatGPT:大模型三强争霸,谁将引领AI未来?

DeepSeek vs. Grok vs. ChatGPT&#xff1a;大模型三强争霸&#xff0c;谁将引领AI未来&#xff1f; 在人工智能领域&#xff0c;生成式模型的竞争已进入白热化阶段。DeepSeek、Grok和ChatGPT作为三大代表性工具&#xff0c;凭借独特的技术路径和应用优势&#xff0c;正在重塑…

【RAG】sPecialized KnowledgE and Rationale Augmented Generation

Why PIKE-RAG? 为什么选择PIKE-RAG? 看介绍,感觉能力特别高大上。看介绍,感觉功能接地气、很实用sPecialized KnowledgE and Rationale Augmented Generation 不是RAG (Retrieval Augmented Generation)In recent years, Retrieval Augmented Generation (RAG) systems h…

C++ Class 基础

在 C 中&#xff0c;class&#xff08;类&#xff09; 是面向对象编程&#xff08;OOP&#xff09;的核心概念之一。类用于定义对象的属性和行为&#xff0c;是封装数据和方法的基本单位。以下是 C 中类的基础知识。 1. 类的定义 类通过 class 关键字定义&#xff0c;基本语法…