Zookeeper实战四工作原理

zookeeper官方文档:

https://zookeeper.apache.org/doc/current/index.html

ZooKeeper 是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。

ZooKeeper 的架构通过冗余服务实现高可用性。

ZooKeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

ZooKeeper 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

 cap与base理论

ZooKeeper 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心。

服务生产者将自己提供的服务注册到 ZooKeeper 中心,服务的消费者在进行服务调用的时候先到 ZooKeeper 中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据。

我们知道在 ZooKeeper 中 Leader 选举算法采用了 Zab 协议。Zab 核心思想是当多数 Server 写成功,则任务数据写成功:

  • 如果有 3 个 Server,则最多允许 1 个 Server 挂掉。

  • 如果有 4 个 Server,则同样最多允许 1 个 Server 挂掉。

既然 3 个或者 4 个 Server,同样最多允许 1 个 Server 挂掉,那么它们的可靠性是一样的。

所以选择奇数个 ZooKeeper Server 即可,这里选择 3 个 Server。

 注意”nofile”项有两个可能的限制措施。就是项下的hard和soft。 要使修改过得最大打开文件数生效,必须对这两种限制进行设定。 如果使用”-“字符设定, 则hard和soft设定会同时被设定。

数据模型

1)znode  zookeeper 中的所有存储的数据是由 znode 组成的,节点也称为 znode,并以 key/value 形式存储数据。

整体结构类似于 linux 文件系统的模式以树形结构存储。其中根路径以 / 开头。

存储的数据在根目录下存在 runoob 和 zookeeper 两个节点,zookeeper 节点下存在 quota 这个节点。

 

 

 runoob 节点是在我们之前章节创建,并且通过 java 客户端设置值 0,现在我们在命令行终端执行 get /runoob 显示此节点的属性。

特点:

(1)同一级节点 key 名称是唯一的

(2)创建节点时,必须要带上全路径

(3)session 关闭,临时节点清除

(4)自动创建顺序节点

(5)watch 机制,监听节点变化

(6)delete 命令只能一层一层删除

提示:新版本可以通过 deleteall 命令递归删除。

2)session

客户端与服务端之间的连接是基于 TCP 长连接,client 端连接 server 端默认的 2181 端口,也就是 session 会话。

从第一次连接建立开始,客户端开始会话的生命周期,客户端向服务端的ping包请求,每个会话都可以设置一个超时时间。

Session 的创建

sessionID: 会话ID,用来唯一标识一个会话,每次客户端创建会话的时候,zookeeper 都会为其分配一个全局唯一的 sessionID。

Timeout:会话超时时间。客户端在构造 Zookeeper 实例时候,向服务端发送配置的超时时间,server 端会根据自己的超时时间限制最终确认会话的超时时间。

TickTime:下次会话超时时间点,默认 2000 毫秒。可在 zoo.cfg 配置文件中配置,便于 server 端对 session 会话实行分桶策略管理

isClosing:该属性标记一个会话是否已经被关闭,当 server 端检测到会话已经超时失效,该会话标记为"已关闭",不再处理该会话的新请求。

Session 的状态

下面介绍几个重要的状态:

  • connecting:连接中,session 一旦建立,状态就是 connecting 状态,时间很短。

  • connected:已连接,连接成功之后的状态。

  • closed:已关闭,发生在 session 过期,一般由于网络故障客户端重连失败,服务器宕机或者客户端主动断开。

会话超时管理(分桶策略+会话激活)

zookeeper 的 leader 服务器再运行期间定时进行会话超时检查,时间间隔是 ExpirationInterval,单位是毫秒,默认值是 tickTime,每隔 tickTime 进行一次会话超时检查。

ExpirationTime 的计算方式:

ExpirationTime = CurrentTime + SessionTimeout;
ExpirationTime = (ExpirationTime / ExpirationInterval + 1) * ExpirationInterval;

 在 zookeeper 运行过程中,客户端会在会话超时过期范围内向服务器发送请求(包括读和写)或者 ping 请求,俗称心跳检测完成会话激活,从而来保持会话的有效性。

 zookeeper 的 ACL(Access Control List,访问控制表)权限,可以针对节点设置相关读写等权限,保障数据安全性。

permissions 可以指定不同的权限范围及角色。

ACL 命令行

  • getAcl 命令:获取某个节点的 acl 权限信息。
  • setAcl 命令:设置某个节点的 acl 权限信息。
  • addauth 命令:输入认证授权信息,注册时输入明文密码,加密形式保存。

ACL 构成

zookeeper 的 acl 通过 [scheme:id:permissions] 来构成权限列表。

  • 1、scheme:代表采用的某种权限机制,包括 world、auth、digest、ip、super 几种。
  • 2、id:代表允许访问的用户。
  • 3、permissions:权限组合字符串,由 cdrwa 组成,其中每个字母代表支持不同权限, 创建权限 create(c)、删除权限 delete(d)、读权限 read(r)、写权限 write(w)、管理权限admin(a)。

案例:

 

 

auth 实例

auth 用于授予权限,注意需要先创建用户。

digest 实例

退出当前用户,重新连接终端,digest 可用于账号密码登录和验证。。

IP 实例

限制 IP 地址的访问权限,把权限设置给 IP 地址为 192.168.3.7 后,IP 为 192.168.3.38 已经没有访问权限。

 

watcher 机制,可以分为四个过程:

  • 客户端注册 watcher。
  • 服务端处理 watcher。
  • 服务端触发 watcher 事件。
  • 客户端回调 watcher。

其中客户端注册 watcher 有三种方式,调用客户端 API 可以分别通过 getData、exists、getChildren 实现。

数据同步

在 Zookeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性。

ZAB 协议分为两部分:

  • 消息广播
  • 崩溃恢复

ZAB 协议的恢复模式使用了以下策略:

  • 1、选举 zxid 最大的节点作为新的 leader
  • 2、新 leader 将事务日志中尚未提交的消息进行处理

leader 选举原理

 leader 选举存在两个阶段,一个是服务器启动时 leader 选举,另一个是运行过程中 leader 服务器宕机。

重要的参数:

  • 服务器 ID(myid):编号越大在选举算法中权重越大
  • 事务 ID(zxid):值越大说明数据越新,权重越大
  • 逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加

选举状态:

  • LOOKING: 竞选状态
  • FOLLOWING: 随从状态,同步 leader 状态,参与投票
  • OBSERVING: 观察状态,同步 leader 状态,不参与投票
  • LEADING: 领导者状态

启动选举流程:

 

每个节点启动的时候都 LOOKING 观望状态,接下来就开始进行选举主流程。这里选取三台机器组成的集群为例。第一台服务器 server1启动时,无法进行 leader 选举,当第二台服务器 server2 启动时,两台机器可以相互通信,进入 leader 选举过程。

(1)每台 server 发出一个投票,由于是初始情况,server1 和 server2 都将自己作为 leader 服务器进行投票,每次投票包含所推举的服务器myid、zxid、epoch,使用(myid,zxid)表示,此时 server1 投票为(1,0),server2 投票为(2,0),然后将各自投票发送给集群中其他机器。

(2)接收来自各个服务器的投票。集群中的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(epoch)、是否来自 LOOKING 状态的服务器。

(3)分别处理投票。针对每一次投票,服务器都需要将其他服务器的投票和自己的投票进行对比,对比规则如下:

       a. 优先比较 epoch

       b. 检查 zxid,zxid 比较大的服务器优先作为 leader

       c. 如果 zxid 相同,那么就比较 myid,myid 较大的服务器作为 leader 服务器

(4)统计投票。每次投票后,服务器统计投票信息,判断是都有过半机器接收到相同的投票信息。server1、server2 都统计出集群中有两台机器接受了(2,0)的投票信息,此时已经选出了 server2 为 leader 节点。

(5)改变服务器状态。一旦确定了 leader,每个服务器响应更新自己的状态,如果是 follower,那么就变更为 FOLLOWING,如果是 Leader,变更为 LEADING。此时 server3继续启动,直接加入变更自己为 FOLLOWING。

2、运行过程中的 leader 选举

当集群中 leader 服务器出现宕机或者不可用情况时,整个集群无法对外提供服务,进入新一轮的 leader 选举。

(1)变更状态。leader 挂后,其他非 Oberver服务器将自身服务器状态变更为 LOOKING。

(2)每个 server 发出一个投票。在运行期间,每个服务器上 zxid 可能不同。

(3)处理投票。规则同启动过程。

(4)统计投票。与启动过程相同。

(5)改变服务器状态。与启动过程相同。

zookeeper 如何实现分布式锁

    排他锁(Exclusive Locks),又被称为写锁或独占锁的应用,利用 zookeeper 的同级节点的唯一性特性,在需要获取排他锁时,所有的客户端试图通过调用 create() 接口,在 /exclusive_lock 节点下创建临时子节点 /exclusive_lock/lock,最终只有一个客户端能创建成功,那么此客户端就获得了分布式锁。同时,所有没有获取到锁的客户端可以在 /exclusive_lock 节点上注册一个子节点变更的 watcher 监听事件,以便重新争取获得锁。

共享锁(Shared Locks),又称读锁应用

1)、客户端调用 create 方法创建类似定义锁方式的临时顺序节点。

 2)、客户端调用 getChildren 接口来获取所有已创建的子节点列表。

3)、判断是否获得锁,对于读请求如果所有比自己小的子节点都是读请求或者没有比自己序号小的子节点,表明已经成功获取共享锁,同时开始执行度逻辑。对于写请求,如果自己不是序号最小的子节点,那么就进入等待。

4)、如果没有获取到共享锁,读请求向比自己序号小的最后一个写请求节点注册 watcher 监听,写请求向比自己序号小的最后一个节点注册watcher 监听。

 

 

 

 

 

 3,基础命令

1)ls 命令

ls 命令用于查看某个路径下目录列表。

2)ls2 命令

ls2 命令用于查看某个路径下目录列表,它比 ls 命令列出更多的详细信息。

3)get 命令

get 命令用于获取节点数据和状态信息。

格式:

get path [watch]
  • path:代表路径。
  • [watch]:对节点进行事件监听。

ex:

 

 4)stat 命令

stat 命令用于查看节点状态信息。

格式:

stat path [watch]

 5)create 命令

create 命令用于创建节点并赋值。

格式:

create [-s] [-e] path data acl

  • [-s] [-e]:-s 和 -e 都是可选的,-s 代表顺序节点, -e 代表临时节点,注意其中 -s 和 -e 可以同时使用的,并且临时节点不能再创建子节点。
  • path:指定要创建节点的路径,比如 /runoob
  • data:要在此节点存储的数据。
  • acl:访问权限相关,默认是 world,相当于全世界都能访问。

 ex: create -s -e /runoob 0

6)set 命令

set 命令用于修改节点存储的数据。

格式:

set path data [version]
  • path:节点路径。
  • data:需要存储的数据。
  • [version]:可选项,版本号(可用作乐观锁)。
注:只有正确的版本号才能设置成功,可以通过get命令查看版本号

 

案例:set /runoob0000000001 0 

 

 

7)delete 命令

delete 命令用于删除某节点。

格式:delete path [version]

  • path:节点路径。
  • [version]:可选项,版本号(同 set 命令)。

8)stat 命令

stat 命令用于查看 zk 的状态信息,实例如下:

echo stat | nc 192.168.3.38 2181

9)ruok 命令

ruok 命令用于查看当前 zkserver 是否启动,若返回 imok 表示正常。实例如下:

 echo ruok | nc 192.168.3.38 2181

10)dump 命令

dump 命令用于列出未经处理的会话和临时节点。实例如下:

 echo dump | nc 192.168.3.38 2181

11)conf 命令

conf 命令用于查看服务器配置。实例如下:

$ echo conf | nc 192.168.3.38 2181

12)cons 命令

cons 命令用于展示连接到服务器的客户端信息。实例如下:

$ echo cons | nc 192.168.3.38 2181

13)envi 命令

envi 命令用于查看环境变量。实例如下:

$ echo envi | nc 192.168.3.38 2181








 





 

posted on 2022-06-29 09:42  让代码飞  阅读(67)  评论(0)    收藏  举报

导航

一款免费在线思维导图工具推荐:https://www.processon.com/i/593e9a29e4b0898669edaf7f?full_name=python