1.Zookeeper的概述

Zookeeper是一个开源的分布式协调服务框架,主要用来解决分布式集群中应用系统的一致性问题和数据管理问题

image.png


2.Zookeeper的特点

zookeeper本质上是一个分布式文件系统,适合存放小文件,也可以理解为一个数据库
image.png
在上图左侧,Zookeeper中存储的其实是一个又一个Znode,Znode是Zookeeper中的节点

  • Znode是有路径的,例如/data/host1,/data/host2,这个路径也可以理解为是Znode的Name
  • Znode也可以携带数据,例如说某个 Znode的路径是/data/host1,其值是一个字符串“192.168.8.1”

正因为 Znode的特性,所以 Zookeeper可以对外提供出一个类似于文件系统的试图,可以通过操作文件系统的方式操作 Zookeeper

  • 使用路径获取 Znode
  • 获取 Znode携带的数据
  • 修改Znode携带的数据
  • 删除Znode
  • 添加Znode

image.png


3.Zookeeper的架构

Zookeeper集群是一个基于主从架构的高可用集群
image.png
每个服务器承担如下三种角色中的一种
Leader角色: 一个 Zookeeper集群同一时间只会有一个实际工作的 Leader,它会发起并维护与各Follwer及 Observer间的心跳。所有的写操作必须要通过 Leader完成再由 Leader将写操作广播给其它服务器。
Follower角色: 一个 Zookeeper集群可能同时存在多个 Follower,它会响应 Leader的心跳Follower可直接处理并返回客户端的读谭求,同时会将写请求转发给 Leader处理,并且负责在 Leader处理写请求时对请求进行投票
Observer角色: 与 Follower类似,但是无投票权。

角色 描述
领导者(Leader) 1:leader是集群工作的核心,集群内部各个服务器的调度者
2:Leader负责进行投票选举

4: 参与集群投票 | | 学习者(Learner) | 跟随者(Follower) | 1: Follower用于接收客户端请求并
向客户端返回结果
2:处理客户端非事务(读操作)请求
3:转发事务请求给 Leader
4:参与集群投票 | | | 观察者(ObServer) | 1: Observer用于接收客户端请求,并
向客户端返回结果
2:处理客户端非事务(读操作)请求
3:转发事务请求给 Leader
4:不参与集群投票 | | 客户端(Client) | | 请求发起方 |


4.Zookeeper leader 选举

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。

1.选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;

2.选举线程首先向所有Server发起一次询问(包括自己);

3.选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;

4.收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;

5.线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。 通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1. 每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。选主的具体流程图所示:

uTools_1615293142215.png

zxid
  • znode节点的状态信息中包含czxid, 那么什么是zxid呢?
  • ZooKeeper状态的每一次改变, 都对应着一个递增的Transaction id, 该id称为zxid. 由于zxid的递增性质, 如果zxid1小于zxid2, 那么zxid1肯定先于zxid2发生.
   创建任意节点, 或者更新任意节点的数据, 或者删除任意节点, 都会导致Zookeeper状态发生改变, 从而导致zxid的值增加.


5.Zookeeper 的数据模型 

  •   层次化的目录结构,命名符合常规文件系统规范
  •   每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识
  •   节点Znode可以包含数据和子节点,但是EPHEMERAL类型的节点不能有子节点
  •   Znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本
  •   客户端应用可以在节点上设置监视器
  •   节点不支持部分读写,而是一次性完整读写

6.Zookeeper 的节点

  •   Znode有两种类型,短暂的(ephemeral)和持久的(persistent)
  •   Znode的类型在创建时确定并且之后不能再修改
  •   短暂znode的客户端会话结束时,zookeeper会将该短暂znode删除,短暂znode不可以有子节点
  •   持久znode不依赖于客户端会话,只有当客户端明确要删除该持久znode时才会被删除
  •   Znode有四种形式的目录节点
  •   PERSISTENT(持久的)
  •   EPHEMERAL(暂时的)
  •   PERSISTENT_SEQUENTIAL(持久化顺序编号目录节点)
  •   EPHEMERAL_SEQUENTIAL(暂时化顺序编号目录节点)