首页 > 其他分享 >ZooKeeper数据和集群特点,ZAB协议和选主过程解析

ZooKeeper数据和集群特点,ZAB协议和选主过程解析

时间:2023-04-05 20:38:28浏览次数:58  
标签:选主 票数 ZooKeeper ZAB 事务 集群 node2 节点 客户端

前言

本文讲述 ZooKeeper 集群架构特点、数据结构、事务ID、选主和ZAB协议具体执行过程。

服务保证

ZooKeeper 非常快速且非常简单。由于它的目标是构建更复杂的服务(如同步)的基础,因此它提供了一组保证:

【顺序一致性】来自客户端的更新将按发送顺序执行,因为只有唯一的主节点负责写请求,所以很容易保证

【原子性】更新要么成功要么失败,没有部分结果

【单一系统映像】无论连接到集群中哪个服务看到的数据都将是一样的

【可靠性】更新操作应用后,会一直存在直到客户重新这个更新

【及时性】保证系统的客户端视图在一定时间范围内是最新的。写入的数据需要同步给其他节点,最终保持一致状态

集群结构和选主

节点间通信

  • 端口说明:2181(对 Client 提供服务);3888(选举 Leader);2888(集群内通讯)
  • 后面的节点和前面每一个节点建立长连接,这样每两个节点之间都会有双向通信的通道

集群结构

  • ZK 是一个有主集群架构,集群只有一个主。
  • 每个节点都需要配置一个唯一服务 id(myid)。
  • 集群类服务分主、从、观察者三种角色。只有主节点处理写请求;所有节点都可以处理读请求;客户端通过从、观察者写入的时候,会将请求转发给主节点处理;从负责选举和顶替主节点;观察者只能负责读请求。
  • 主节点宕机,集群会进入不可用状态,需要选主成功后才能对外提供服务;选主速度是非常快的,官方说选主时间不到 200 毫秒;需要过半节点参与才能成功。
  • 选主的时候优先事务 id(ZXID) 值最大的,值越大就代表数据越新;再而优先服务 id(myid) 最大的。
  • 客户端跟集群中节点建立连接会产生唯一 sessionId,通过这个来识别是否同一客户端。

在这里插入图片描述

第一次启动集群选主

第一次启动集群所有节点的事务 id(ZXID) 都是 0,所以对比服务 id(myid) 最大的服务 node4 成为主节点。

在这里插入图片描述

重新选主

  • node4 宕机,其他 3 个节点开始选举

在这里插入图片描述

  • 具体选举过程:

【1】node3 最先发现 node4 宕机,记录投自己 1 票,然后发送选举通知给其他节点
【2】node1 和 node2 收到 node3 的选举消息对比事务ID(ZXID)都比其大,所以否决了 node3 并返回
【3】同时触发 node1 和 node2 选举,各自记录投自己 1 票,然后发送选举通知给其他节点

票数/节点 node1 node2 node3
n1票数 1 0 0
n2票数 0 1 0
n3票数 0 0 1

【4】node3 收到 node1 和 node2 的选举通知,对比发现自己的事务ID比两者都小,所以同意了这两票并记录
【5】同时 node3 反投两者一票,自己记录,并通知他们

票数/节点 node1 node2 node3
n1票数 2 1 2
n2票数 1 2 2
n3票数 0 0 1

【5】node1 收到 node2 的选举通知,对比事务ID一样大,但是 node2 服务ID(myid) 更大,所以同意这 1 票
【6】同时 node1 反投 node2,自己记录,并通知他们

票数/节点 node1 node2 node3
n1票数 2 1 2
n2票数 3 3 3
n3票数 0 0 1

【6】node2 收到 node1 的选举通知,对比事务ID一样大,但是自己的服务ID(myid) 更大,所以否决了 node1 并返回,各自记录票数不变
【7】最终三个节点记录 node2 票数一致且最高,新主选为 node2。事务ID 代表纪元(epoch)的高 32 位值 +1,代表事务递增序号的低 32 位清零

数据节点

类型

ZK 是一个目录树结构,每一层目录可称之为节点。节点可以存储对应的数据,但是大小不能超过 1M,所以 ZK 适合作协调服务而不适合作数据库。

节点有三种类型(持久、临时、序列),一个节点只能持久、临时二选一,但是可以兼具序列节点的特点。临时 + 序列适合做分布式锁。不用担心锁过期、续期问题,只要保持连接就行。

【持久节点】会写到磁盘,重启可恢复

【临时节点】会和连接的 sessionId 绑定,连接断开一定时间后节点消失;且所有服务会同步这个 sessionId 绑定信息,一定时间内客户端通过相同的 sessionId 重新连接或者切换到其他服务临时节点不会消失。

【序列节点】多个请求创建同一个目录会按统一规范命名(名称 + 序号)保证唯一性。

节点信息

节点包含下列关键信息:

【cZxid】创建事务 id

【ctime】创建时间

【mZxid 】修改事务 id。开始和 cZxid 一致,如果修改了节点的数据会变成新的事务 id

【mtime】最后修改时间

【pZxid】节点下创建最后节点 id。开始和 cZxid 一致,每当在该节点下创建新节点,会变成最新创建节点的 cZxid

【ephemeralOwner】创建该临时节点的客户端 sessionId

事务ID

ZK 集群只有主节点负责写操作,它维护一个递增的事务ID。前 32 位是 Leader 纪元(epoch),从 1 开始,每选举一次新主 +1;后 32 位是事务递增序号,从 1 开始,每个写操作(增/删/改节点、客户端建立连接产生 sessionId)都会 +1。

日志解读

通过 zkCli.sh 连接 ZK 服务。

创建第一个节点 /test 同时赋值。

【cZxid = 0x100000002】产生了两个事务(产生连接并生成了 sessionId;创建了 /test 节点同时赋值),所以事务 id 递增到了 2;

【mZxid = 0x100000002】未修改 /test 节点,初始值和 cZxid 一致;

【pZxid = 0x100000002】/test 未创建子节点,初始值和 cZxid 一致;

【ephemeralOwner = 0x0】因为默认创建的不是临时节点,所以没绑定 sessionId。

在这里插入图片描述

修改 /test,mZxid 变成了修改事务的 id 0x100000003。

在这里插入图片描述

在 /test 下创建子节点 /child,可以看到 /test 节点的 pZxid 和 子节点的 cZxid 保持一致。因为 pZxid 记录的是最后创建的子节点的 cZxid。

在这里插入图片描述

创建临时节点,ephemeralOwner 和当前客户端 sessionId 绑定。

在这里插入图片描述

Paxos

Paxos 是分布式计算中消息传递的一致性算法理论,可参考这篇 《Paxos 算法理论》 。而 Raft、ZAB 等算法都是在 Paxos 基础上的进行改进或简化而生,都应用在有主集群架构。

ZAB

ZAB(Zookeeper Atomic Broadcast) 协议有崩溃恢复和消息广播两种基本的模式。

消息广播

消息广播整体是一个两阶段提交过程。主节点处理更新事务后广播给从节点预提交,从节点写事务日志并反馈给主节点;主节点只要收到过半反馈再广播从节点提交更改到内存或持久化。

【1】—客户端通过从节点服务提交了写请求

【2】—从节点不能执行写操作,将操作提交给主节点

【3】—主节点生成唯一事务 id(cZxid)

【4】—主节点通过与每个从节点建立的单独队列提交提案(proposal)

【5】—从节点收到提案后,写日志,向主节点返回确认提案(ACK)

【6】—主节点收到过半节点确认提案后,自己提交(commit)并通过队列广播给从节点,如果未过半则操作无效。从节点收到提交消息会将数据写入内存,或者持久化

【7】—主节点向从节点返回操作结果

【8】—从节点将结果返回给客户端

在这里插入图片描述

崩溃恢复

Leader 宕机后进入崩溃恢复,先通过选举产生新主,再进入同步过程。

旧主如果在广播 proposal 之前宕机,那不会有从节点收到这个事务消息,新主自然也不会有,这个事务就丢失了。后面旧主再次加入集群会成为 Follwer 因为集群事务ID已经进入了新的纪元,旧主的事务ID小于当前,旧主之前的 proposal 也会因为数据同步回滚掉。

如果新主有之前收到的预提交(proposal) ,则会继续完成这个事务。

其他特点

  • ZK 保证 CAP 中的 C(一致性)和 P(分区容错性)。

一致性体现在客户端访问任何服务节点数据都是一致的,但是这种是最终一致,因为更新广播给其他节点有两阶段(proposal、commit)提交过程。如果主广播 commit 之后,其他节点处理完成,但是客户端通过还未处理或收到 commit 的节点访问这个数据,是访问不到的。虽然它最终会和整个集群保持一致状态,但并不是那种强一致。不过可以通过客户端发起 sync 操作让该节点同步,回调后再发送读取操作来保证数据是最新的。

  • ZK 保存的数据是二进制安全的

它不管客户端使用何种编码,都按二进制存储。客户端自己处理编解码过程,只要编解码一致,数据就不会有问题,这一点和 Redis 一致。

参考链接

Paxos 算法理论

Apache ZooKeeper 概览

标签:选主,票数,ZooKeeper,ZAB,事务,集群,node2,节点,客户端
From: https://www.cnblogs.com/shuiyao3/p/17290785.html

相关文章

  • 在Linux搭建Zookeeper集群
    前言本文讲述在多台Linux服务器搭建ZooKeeper集群的具体步骤,共4个节点(1主2从1观察者)。ZooKeeper使用的端口:【2181】对client提供服务;【3888】选举leader;【2888】集群内通讯。准备工作ZooKeeper需要1.7及以上版本的JDK,可以参考在Linux安装JDK。给系统配置hosts......
  • Zookeeper Session源码
    我们说客户端与服务端建立连接交互的时候会创建一个Session与之对应,那假设客户端请求来了,服务端是如何处理的?Session又是如何创建出来的?我们先来看第一个问题:服务端如何处理客户端发来的请求?一、如何处理请求所谓的请求全称是网络请求,涉及到网络就少不了Socket通信,ZooKeep......
  • Docker 部署单机 Zookeeper + exporter
    目录资源清单一、Docker安装1.使用国内yum源2.卸载旧版本的docker3.安装Docker20.10版本4.设置镜像加速5.启动docker二、Docker-compose安装1.Docker-compose安装2.查看docker-compose版本三、部署服务1.docker-compose.yaml资源清单2.创建目录结构3./conf/......
  • A1--Zookeeper部署
    (1)将/data/zookeeper/conf 这个路径下的 zoo_sample.cfg 修改为 zoo.cfgmv zoo_sample.cfgzoo.cfg (2)打开 zoo.cfg 文件,修改 dataDir 路径:vimzoo.cfg修改数据存储路径配置dataDir=/data/zookeeper/zkData......
  • linux 系统安装 zookeeper
     下载zookeeper安装包http://mirror.bit.edu.cn/apache/zookeeper/选择3.4.14版本   上传到服务器,并解压到指定目录tar-zxvfzookeeper-3.4.14.tar.gz-C/usr/local/进入/usr/local/zookeeper/config目录1、复制文件重命名cpzoo_sample.cfg......
  • Serializable接口 和 serialVersionUID 的关系
    结论建议实现了Serializable手动生成serialVersionUID一般认为实现了Serializable接口,不手动生成serialVersionUID不会出问题。如果没有手动生成,序列化和反序列化的时候,通过类所有字段算一个serialVersionUID出来,但是据说不同jvm可能算的不一样。实现了Serializable......
  • linux 系统安装 zookeeper
      下载zookeeper安装包http://mirror.bit.edu.cn/apache/zookeeper/选择3.4.14版本   上传到服务器,并解压到指定目录tar-zxvfzookeeper-3.4.14.tar.gz-C/usr/local/进入/usr/local/zookeeper/config目录1、复制文件重命名cpzoo_sample.c......
  • Zabbix利用脚本方式实现邮件报警
    一、安装mailx并配置好能够通过第三方发送邮件yum-yinstallmailxvimmail.rc#在末尾添加如下内容(以163邮箱为例):#setforzabbixsetsendcharsets=iso-8859-1,utf-8#发件人[email protected]#smtp服务器地址setsmtp=smtp.163.com#需要登录认证setsmtp-auth=lo......
  • kafka、zookeeper入门
    ZooKeeper基础与入门1、ZooKeeper概念介绍在介绍ZooKeeper之前,先来介绍一下分布式协调技术所谓分布式协调技术主要是用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种共享资源,防止造成资源竞争(脑裂)的后果。这里首先介绍下什么是分布式系统所谓分布式系统......
  • Zookeeper Session原理
    我们的Leader已经选举出来了,那接下来该干什么呢?你或许很快能想到,那就是数据同步。通俗地讲,就是Leader选出来了,各自的角色都确定好了,那Follower和Observer自然要同Leader建立连接同步数据,这里就引入了ZooKeeper的另一个核心知识:Session。一、什么是Session?Session......