写点什么

分布式管理员 zookeeper

用户头像
卢卡多多
关注
发布于: 2021 年 06 月 08 日
分布式管理员zookeeper

晚上好,我是卢卡,发现很多技术学的不太扎实,比如经典的 zookeeper,Apache zookeeper 开源的分布式协调通知,对于电商系统,高并发,以及微服务的系统服务适用信息都比较高。重新再学习了一下,总结下自己的知识点,对知识点提炼和自己的理解很有帮助,技术人生从重学技术点开始。


zookeeper 的定位

Zookeeper 是 apache Zookeeper 开源的项目,


Zookeeper 的主要作用


对于微服务分布式的协调管理,元数据的管理,Master 选举, 实际使用场景下,主要是三类项目

1.zookeeper 的适用方向

① 后端以 Java 为主的电商类管理系统


Zookeeper 主要作用于 分布式锁,注册中心 ,这里 Zookeeper 主要保持 CAP 理论中的 CP(一致性和分区容错性),也就是说 Zookeeper 保证的是强一致性


②对于大数据存储,数据管理,主从数据切换等系统


这里我们熟知的 Kafla,canal 等在使用 Zookeeper 的元数据管理 ,通过 master 选举出具体的主从,ZAB 原子一致性协议,


③大型互联网公司,自研的分布式组件


一般以 zookeeper 为原型, zookeeper 已经被大规模的工业级适用于主要的分布式系统,做元数据管理,以及注册中心,一般使用于 dubbo+Zookeeper 做一个基本的微服务架构来实现基本的数据调用


小总结:


zookeeper 分布式协调系统, 封装了分布式架构中所有的核心和主流的需求和功能;


分布式锁, 元数据管理, master 选举, 分布式协调和通知

zookeeper 的基本特性:


​ 在了解 zookeeper 的基本架构之前,我们来了解一下,zookeeper 为什么可以实现分布式系统的协调通知, 元数据管理等;


​ 熟悉 zookeeper 技术栈的都比较了解,它本身是处于通知协调机制,数据同步方面有很强的处理能力,这也就是为什么很多自研的框架,底层都用 zookeeper 的原因,好了,废话不多说,我们开干;


背景:


集群环境下,zookeeper 集群搭建了 3 台物理机器;


1.顺序一致性


 多个请求,不管是读取数据的,还是说写入数据的,都要按照顺序执行; zookeeper内部要处理的请求,leader角色会给每一个请求分配一个全局唯一且自增的ZxID,用于请求数据  //这个唯一的全局ID就保证了顺序一致性这里的zxid,先简单了解,作为一个请求的排列序号,后面会重点讲解的
复制代码


2.原子性


要么全部机器都成功,要么全部机器都不成功,在同步数据操作时  //保证每次同步操作结果都是一致的
复制代码


3.高可用性


集群化部署,避免宕机,
如果宕机,也可自己选举leader,重新提供服务 //从恢复模式到消息广播模式
复制代码


4.数据一致性:


 集群情况下,每台机器上的数据都是一致的,但是如果说,在数据同步的时候,宕机了, 其他机器会自动将数据保存到磁盘日志中,等到leader角色提交之后,才会同步到znode节点中,真正实现数据在每台机器都是一致的  //这里说的数据一致性,是强一致性,也是zookeeper的核心的特性,根据分布式系统保持的CAP理论,只能支持CP, //其中C-consistency ,一致性对于,数据的强一致性,p-为系统的分区容错性  A-高可用性,其eureka就是支持AP特性
复制代码


5.高性能性


高性能,这里提出一个zookeeper的数据模型,znode节点//znode节点,基于纯内存的,速度很快,树形结构,类似于Linux的文件系统,每个节点都有数据    存储的数据,已经可以处理的能力也就比较强,后面会仔细讲的,接着看下去吧
复制代码



小总结:


基于 zookeeper 的集群架构的特点图:


zookeeper 的集群化:

背景:


和上述的场景一致,都是 3 台机器,自动化部署的 zookeeper 集群,现在我们来具体拆分下每个机器的主要功能


Zookeeper 的同步数据,是经过主 leader 提交 commit 然后同步到各个 follow 角色 :2PC 提交事务--留个念想,后面细聊

1.Zookeeper 集群化角色划分:

  • Leader(领导)


集群启动后,根据半数选举成功的机器,成为 Leader 角色,支持读写,主要用于写操作,


  • Follower(候选人)


剩余的选举不成功,为 follower 角色,支持读取数据和同步数据,(leader 宕机,提供不了写数据操作时,其他 Follower 中选举出新的 L earner 来实现写数据的操作)


  • Observer


只是支持读取数据,不参与 leader 的竞争


这里面角色都是自身理解,也可以说成模式等等;


当每个角色确定功能之后,我们可以将数据直接开始同步,提供服务;


1.1 注意事项:

​ 当一个写操作的请求直接访问 follower 角色的 zookeeper 的进程时,follower 角色处理不了写操作,因为自身没有权限,只有 Leader 角色处理写操作的请求,这样的话,follower 角色就会转发请求到 Leader 角色处理此请求,处理之后,开始数据同步,然后返回到其他 follower 角色,完成数据同步,阿虎;

2.Zookeeper 集群与客户端访问的过程:

背景:


​ Zookeeper 集群化,处理请求,可能来源于消息队列,或者是单独的发生请求读取数据,等等;那么每个请求到底是怎么连接到 Zookeeper 集群建立连接的呢,这节我们来具体聊聊?


当Zookeeper的集群环境下启动成功,然后我们开始分配角色,然后我们集群于客户端开始建立TCP的长连接,
复制代码


当建立连接后,就会产生一个服务端的 session ,形成一个会话的机制,相应的也会有 sessionTimeout 的存在


如果当前环境下,突然连接中断了,在 sessionTimeout 时间内连接成功不会影响此次长连接的使用;

3.Zookeeper 集群化的数据一致性是怎么保证的?

背景:


​ 上述说到 Zookeeper 支持 CAP 理论中的 CP ,主要是 consistency,一致性; 他保证数据强一致性,就很有自己的架构特点,我们来一步步揭开 Zookeeper 怎么保证强一致性的面纱?


Zookeeper 的强一致性是通过: ZAB(Zookeeper Atomic Broadcast) 协议: 原子广播协议


这个协议是 Zookeeper 的数据操作的核心,也用于元数据管理的关键;


协议来进行 Zookeeper 集群之间的数据同步,保证数据的强一致性;


ZAB: zookeeper Atomic broadcast 协议的思想:


划分角色: leader 和 follower


发送一个 Proposal(提议),leader 给所有的 follower 都同步一个 proposal(提议)如果半数以上的 follower,都收到事务的 proposal 提议,每个 follower 都会返回一个 ack


每个提议 Pproposal ->先不会写入 follower 中 znode 数据中,而是会往一个自己本地磁盘日志文件中写入,然后返回给 leader 一个 ackleader 会发送一个 commit 提交事务


半数提交:2PC 也就是两个阶段提交;leader 如果异常宕机,会从 follower 中重新选举;

4.Zookeeper 集群化数据同步的过程:

划分的比较细,坚持看完一定会有收获的⛽️


1⃣️当集群启动的时候,选举算法开始进行在机器中分配 leader 和 follower 角色,通过半数选举机制成功选到 leader 角色的机器


2⃣️剩下的当然就是 follower 角色的机器了,然后可以向外提供服务了


3⃣️当一个(写操作)请求经过 Zookeeper 集群后,leader 角色机器会优先分配一个 zxid 用于创建节点或者变更节点的全局唯一自增 ID,然后将发起一个提议 Proposal(只是一个提议,相当于告诉其他人来活了,准备一下),将提议都放入,之前给每个 follow 角色准备好的队列中,(这里到可以保证顺序一致性)。


4⃣️每个 follower 角色的机器,拿到提议 proposal,然后将数据放入自身的磁盘日志文件中,(不会放入 znode 节点),然后给 leader 节点回复一个 ACK(确定连接成功,返回的确定字符)


ACK (Acknowledge character)即是确认字符:     //在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。    在TCP/IP协议中,如果接收方成功的接收到数据,那么会回复一个ACK数据。通常ACK信号有自己固定的格式,长度大小,由接收方回复给发送方。
复制代码


5⃣️当 leader 角色的机器,拿到半数以上的 follower 角色机器返回的 ACK 之后,代表已经准备成功,leader 角色会推送一个 commit 消息,


其他 follower 就会将数据从磁盘文件写入,自身进行 znode 节点中存储起来,提交之后,数据同步完成,也就可以读取数据了


因为这个过程,分了两阶段提交,又称为 2PC 事务,用于解决分布式事务的方法

5.Znode 的数据模型:

1.zookeeper 的数据模型是,


基于纯内存的树形结构: Znode


 znode分类:
​ 持久节点:客户端与zk断开连接,节点依旧存在​ 临时节点:客户端与zk断开连接,节点消失​ 顺序节点: 对于创建节点的时候,自增加全局递增的序号;
复制代码


zk 中有一个基于分布式锁的要求环境,curator 框架,我们开展临时节点来实现的,加锁的时候创建一个顺序节点


2.zk 节点的用途


zookeeperk 做元数据管理的时候: 肯定是持久节点但是一般做分布式锁,分布式协调和通知,都是临时节点,如果断开,临时节点消失,


3 .znode 的节点的组成部分:


![img](file:///private/var/folders/5j/9nz1gp6d53b2tfxnrl8xg6yr0000gn/T/WizNote/d07bc0e0-88a1-4a6a-8702-1fd8a335449c/index_files/af5843a0-09d9-4a98-b236-7c6dc3c0b768.jpg)

6.zookeeper 启动集群到数据同步过程

leader 选举


集群启动,开始进行 leader 选举,半数机器认可当前机器作为 leader,各个 follower 开始进行数据同步,完成就可以退出恢复模式,然后可以的对外提供服务了


宕机重新选举 leader


3 台机器,允许不超过一半的机器宕机


2 台机器, 两个机器都同意某台机器作为 leader ,这个就可以选举出 leader;


1 台机器是没法自己选举自己的;因为 1 台机器,小于半数,所有不能启动集群环境了;


数据同步


leader 选举出来后,其他机器都是 follower--开始数据同步


强制剩下的 follower 数据与自己 leader 一致;


数据同步完成之后,就会进去, 消息广播模式;


消息写入: leader 写入,采用 2PC 模式过半写机制,给 follower 进行同步


将自己数据更新到,znode 数据节点中


宕机修复


leader 宕机,或者 follower 宕机,只要存活的机器超过一半,那就可以重新选举 leader 选举 leader,要求有一半以上的支持 ,其他跟 follower 数据同步,消息广播模式


zk 从恢复模式到消息广播模式开始同步数据


7.谈谈在 zookeeper 集群下数据一致性的理解?

​ 在数据同步的过程中,leader 将提议 proposal 放入队列(先进先出),然后开始同步到 follower,当过半的 follower 返回 ACK(确认字符)之后,leader 直接推送一个 commit 用于提交,follower 同步数据;(这里我们注意,不是全部的 follower 返回结果)


zk 的数据同步不是强一致性,


当 follower 将磁盘日志文件中的数据,提交到 znode 之后,数据才可以被读取到,最终数据会一致的,但是


zk 官方给的一个回复是,顺序一致性,会根据 zxid,以及提议 proposal 的顺序保证


因为 leader 一定会保证所有的 proposal 同步到 follower 上,是按照顺序,最终实现顺序一致性


zk 也可以支持强一致行,但是需要手动调节 zk 的 sync()操作

8.ZAB 协议下,数据不一致的情况有哪些?

情况 1:


当 leader 推送一个 commit 提交数据,刚自己提交了,但是他还没有吧 commit 提交给 follower 的时候,就已经挂掉了?


简介: 当客户端发送一个写操作的请求,leader 已经收到半数以上 follower 发来的 ack,他自己本地已经将数据写入 znode 中,leader 自己 commit 成功,但是在没有给别的 follower 发出 commit 之前就已经挂了, 客户端在收到,leader 已经 commit 数据之后,就默认已经将数据更新完成,但是我们新请求,查询数据 follower 机器的时候,发现没有,与之间 leader 返回的不一样;(导致了数据不一致)


这时,follower 中的数据和刚刚宕机的 leader 机器上的数据肯定是不一致的,接下来 zk 会怎么做呢?


在具体的时间中,zk 集群中的 follower 角色发现,老大 leader 无法回复,处于失联,宕机状态,他们就说我们再选一个 leader,然后就再重新选一个 leader01(新的),那之前已经挂掉的 leader,就顺势变成了 follower,


情况 2:


如果客户端在,请求写数据操作的 leader 机器上,然后 leader,发送一个 proposal 提议,但是还没发出去,就挂了;


导致本地磁盘日志文件中存在一个 proposal;但是其他的 follower 中没有这个数据;


当集群奔溃之后,开展恢复模式,ZAB 协议的关键核心就显示出来了,根据


情况 1 的解决思路:


众多的 follower,开始半数选举机制,选出新的 leader 之后,发现本地磁盘上有没有提交的 proposal,然后查看别的 follower 也存在这样 的情况,这里的新 leader(是之前未接收到 commit 消息的 follower),然后我们开始发送 commit 给其他 follower,将数据写入 znode 节点中 解决客户端读取数据不一致的情况;


情况 2 的解决过程:


根据上述的情况,已经宕机的 leader 存在一个 proposal 的提议,但是其他的 follow 没有收到,所以在恢复模式之后,新的 leader 被选择出来,开展写操作,但是发优先去查询一下本地磁盘中是否有之前遗留的 proposal 提议,查询到一个 follower(之前宕机的发送的一个 proposal 的 leader)磁盘数据与其他的不一致,然后现在的新 leader 将会同步数据给其他的 follower,之前宕机的 leader 存在一个的提议(proposal 提议)会被舍弃掉;

9.奔溃恢复时选举出来的新 leader 如何跟其他 follower 进行同步数据的过程

我们还是来模拟一个场景,5 台机器的 zookeeper 集群化部署


其中四台是 follower 角色用于读取数据和同步数据的,剩下的一台就是 leader 专门进行写操作的机器


背景:


​ 当一个 leader 发出一个 proposal 提议后,其他三台的 follower 机器都收到了,唯独剩下的一个没收到 proposal,但是现在已经有三台 j follower 机器已经返回了 ack 的确认字符, 所以 leader 判断已经都通知成功,(半数选举),然后自身开始 commit,没等到给剩下的 follower 角色进行提交就宕机了;



分析一下:


​ 目前 leader 已经 commit 数据到自己的 znode 节点上了,但是已经挂了,但是其他四台 follow 机器,三台已经将 proposal 放到自己本地的磁盘日志文件中,剩余一台啥都没有(之前半数返回 ack 已经够了没有收到 proposal 提议),万一其他三台机器恢复机制时,都选举最后一台机器,作为新的 leader,那这条数据就永久丢失了


先告诉大家一个答案,就是这中事情不会发生,zookeeper 集群不会选择一个没有数据的角色选举成 leader


主要是要了解一个 zxid 的概念:


Zxid: 可以理解为一个事物的自增 ID,要是对提议改变了,他就自增,


要是这个 follow 没有收到提议,也就 zxid 相应的比收到返回 ack 的 follower 节点的机器肯定是大的;


选举 leader 的要求是,在 follower 中,收到事务 zxid 最大的,也就是相当于创建时间最早的,作为新的 leader

10.zxid

  • znode 节点的状态信息中包含 czxid, 那么什么是 zxid 呢?

  • ZooKeeper 状态的每一次改变, 都对应着一个递增的 Transaction id, 该 id 称为 zxid. 由于 zxid 的递增性质, 如果 zxid1 小于 zxid2, 那么 zxid1 肯定先于 zxid2 发生.

  • 创建任意节点, 或者更新任意节点的数据, 或者删除任意节点, 都会导致 Zookeeper 状态发生改变, 从而导致 zxid 的值增加.


​ ZooKeeper 中 ZXID 是一个长度 64 位的数字,其中低 32 位是按照数字递增,即每次客户端发起一个 proposal,低 32 位的数字简单加 1。高 32 位是 leader 周期的 epoch 编号。也就是 leader 的一个版本号


比如说后面 epoch 编号为 8, 也就说当前的 leader 版本是 8 ,挂掉之后重新选举就自增 1,epoch 的编号就是 9


所以睡要是想之前的情况 2,发生就知道是为什么会出来丢掉的数据,因为会找 leader 的 epocn 最大的一个版本作为可以提交的领导者


重新发号命令;

11.Observer 节点(角色)的作用:

需要配置文件,只会单纯的接受和同步数据,observer 不会参与过半写机制,不参与选举


只是被动的接受数据,


如果读的请求需求很大,我们可以添加几个 Observer,


优点:


  • ​ 可一扛下很大的并发量,

  • ​ 不会影响过半写的机制,

  • ​ 不会特别影响性能


原因:


要是都是 follower 节点的话,当 leader 要发 proposal 提议,要等待过半的机器返回 ack,然后同步数据,也是过半的,


选举的时候也是过半的,这样会很耗费时间以及网络资源,但是只要读取的数据,不参与选举的 observer 就很大程度上解决了这个痛点

12.zookeeper 适用于实际部署场景:

​ 适用于小集群的部署,读多写少的场景;


奇数台机器,半数选举,


过半写+磁盘日志文件====》commit+znode 节点


主要是写入压力过大 leader

发布于: 2021 年 06 月 08 日阅读数: 13
用户头像

卢卡多多

关注

还未添加个人签名 2020.04.12 加入

还未添加个人简介

评论

发布
暂无评论
分布式管理员zookeeper