Zookeeper(1)-概述

 

目录

ZooKeeper:分布式应用程序的分布式协调服务

1. 安装

2. 使用

3. 构建zookeeper集群

4. paxos

5. ZAB 协议

5.1 ZAB选主

6. watch机制

6.1 特征

6.2 watch的使用方式

6.3 持久的、递归的手表

6.4  watch事件分类

创建节点

7. ZooKeeper 会话


ZooKeeper:分布式应用程序的分布式协调服务

ZooKeeper 是分布式应用程序的分布式开源协调服务。它公开了一组简单的原语,分布式应用程序可以基于这些原语来实现更高级别的同步、配置维护以及组和命名服务。它被设计为易于编程,并使用以熟悉的文件系统目录树结构为样式的数据模型。它在 Java 中运行,并且具有 Java 和 C 的绑定。

1. 安装

官网https://zookeeper.apache.org/

下载:https://zookeeper.apache.org/releases.html 

zookeeper运行需要jvm环境,所有需要提前安装jdk

2. 使用

windows环境,

zkServer.cmd 服务端启动,zkCli.cmd 客户端连接

linux环境,

zkServer.sh 服务端启动,zkCli.sh客户端连接

连接客户端进行简单的命令操作。

https://zookeeper.apache.org/doc/current/zookeeperCLI.html 使用指南。

  •         addauth scheme auth 添加超级用户

addauth scheme zookeeper:admin

 

  •         close 关闭此客户端/会话
  •         config [-c] [-w] [-s] 显示仲裁成员的配置
  •         connect host:port  连接 ZooKeeper 服务器
  •         create [-s] [-e] [-c] [-t ttl] path [data] [acl]  创建目录和数据 

create  path data 持久,znode被创建后,创建其的client连接断开或者zookeeper服务重启,该节点都会依然存在 persistent_node

create -e path data 临时,当创建改znode的client与zookeeper的连接断开时,znode会被自动删除,临时模式znode不能有child node。执行quit后 。ephemeral_node 

create -s path data 序列,znode被创建后,znode名称会自动添加一个编号,编号会自动递增。 persistent_sequential_node 

create -e -s path data临时+序列 和临时(ephemeral)模式一样,在创建znode的client和zookeeper断开连接后,znode被自动删除,创建时名称会自动添加编号,编号会自动递增 ephemeral_sequential_node 

create -t​​ 3000 /ttl_node data 创建一个过期时间的node,3秒后消失

 

  •         delete [-v version] path 删除指定目录下节点
  •         deleteall path [-b batch size] 删除/path下所有节点
  •         delquota [-n|-b] path  删除路径下的配额
  •         get [-s] [-w] path 获取指定目录下的数据

get /path

 get -w /path -w 设置监视数据更改,注意:打开打印监视

[zkshell: 12] get -w /latest_producer_id_block {"version":1,"broker":0,"block_start":"0","block_end":"999"} [zkshell: 13] set /latest_producer_id_block mydata WATCHER: : WatchedEvent state:SyncConnected type:NodeDataChanged path:/latest_producer_id_block ```

get -s /path 显示统计信息

cZxid :创建节点的id        0纪元第4次操作
ctime : 节点的创建时间 
mZxid :修改节点的id      0纪元第4次操作
mtime :修改节点的时间 
pZxid :子节点的id
cversion : 子节点的版本
dataVersion : 当前节点数据的版本
aclVersion :权限的版本
ephemeralOwner :判断是否是临时节点
dataLength : 数据的长度
numChildren :子节点的数量

 

  •         getAcl [-s] path 获取一条路径的ACL权限

bash [zkshell: 4] create /acl_test mydata ip:127.0.0.1:crwda Created /acl_test [zkshell: 5] getAcl /acl_test 'ip,'127.0.0.1 : cdrwa [zkshell: 6] getAcl /testwatch 'world,'anyone : cdrwa

 

 

  •         getAllChildrenNumber path 获取特定路径下的所有子节点数
  •         getEphemerals path 获取此会话创建的所有临时节点
  •         history 显示有关您最近执行的 11 个命令的历史记录
  •         listquota path 列出一条路径的配额
  •         ls [-s] [-w] [-R] path  列出一条路径的子节点

-s 显示统计信息

-R 递归显示子节点

-w 设置监视孩子的变化,注意:打开打印手表,当删除node是,会监控到

[zkshell: 39] ls -w /brokers [ids, seqid, topics] [zkshell: 40] 删除/brokers/ids WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/brokers ```

 

  •         printwatches on|off  无论是否打印watch,都可以打开/关闭开关

 

 

  •         quit 退出
  •         reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*] 重新配置

将follower 2更改为观察者并将其端口从2182更改为12182

将观察者 5 添加到集合中

从整体中移除观察者 4

[zkshell: 1] reconfig --add 2=localhost:2781:2786:observer;12182 --add 5=localhost:2781:2786:observer;2185 -remove 4 提交新配置:server.1=localhost:2780:2785 :participant;0.0.0.0:2181 server.2=localhost:2781:2786:observer;0.0.0.0:12182 server.3=localhost:2782:2787:participant;0.0.0.0:2183 server.5=localhost:2784: 2789:观察者;0.0.0.0:2185 版本=1c00000002

 

  •         redo cmdno

使用历史记录中的索引重做 cmd。

先用history命令展示,用redo 命令执行

history 0 - ls / 1 - get /consumers 2 - get /hbase 3 - ls /hbase 4 - history [zkshell: 5] redo 3 

 

  •         removewatches path [-c|-d|-a] [-l]   删除节点下的手表。
bash [zkshell: 1] get -w /brokers null [zkshell: 2] removewatches /brokers WATCHER:: WatchedEvent state:SyncConnected type:DataWatchRemoved path:/brokers

 

  •         set [-s] [-v version] path data 设置/更新路径上的数据。

  -s 显示此节点的状态 set -s /hello aaa

-v 使用 CAS 设置数据,可以使用 stat 从 dataVersion 中找到版本。set -v 4 /hello aaa

  •        - setAcl [-s] [-v version] [R] path acl 为一个节点设置 Acl 权限  setAcl /hello auth:user1:12345:crwad

ACL 权限控制,使用:scheme:id:perm 来标识,主要涵盖 3 个方面:
  权限模式(Scheme):授权的策略
  授权对象(ID):授权的对象
  权限(Permission):授予的权限

1.  scheme  采用何种方式授权

  world:默认方式,相当于全部都能访问 setAcl /hello  world world:anyone:crwda
  auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户) ,需要先添加auth ,addauth digest user:pwd, 然后 setAcl /hello world auth:user:pwd:crwda
  digest:即用户名:密码这种方式认证,这也是业务系统中最常用的。用 username:password 字符串来产生一个MD5串,然后该串被用来作为ACL ID。认证是通过明文发送username:password 来进行的,当用在ACL时,表达式为username:base64 ,base64是password的SHA1摘要的编码。 digest:username:BASE64(SHA1(password)):cdrwa
  ip:使用客户端的主机IP作为ACL ID 。这个ACL表达式的格式为addr/bits ,此时addr中的有效位与客户端addr中的有效位进行比对。setAcl /hello world ip:127.0.0.1:crwda 节点只允许IP为127.0.0.1的客户端能读写该写节点的数据

2.  ID   给谁授予权限

id是验证模式,不同的scheme,id的值也不一样。

scheme为digest时,id的值为:username:BASE64(SHA1(password)),

scheme为ip时,id的值为客户端的ip地址。

scheme为world时,id的值为anyone。

scheme为auth时,id为 username:password。

  授权对象ID是指,权限赋予的用户或者一个实体,例如:IP 地址或者机器。授权模式 schema 与 授权对象 ID 之间

3.  permission   授予什么权限

  CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,这5种权限简写为crwda

注意:

  这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限

更详细的如下:

  CREATE   c 可以创建子节点
  DELETE   d 可以删除子节点(仅下一级节点)
  READ       r 可以读取节点数据及显示子节点列表
  WRITE     w 可以设置节点数据
  ADMIN     a 可以设置节点访问控制列表权限

  •         setquota -n|-b val path 在一个路径中设置配额

 限制子节点的数量(包括本身)

setquota -n 2 /quota_test 

-b 限制一条路径的字节数(数据长度)

 setquota -b 5 /brokers

  •         stat [-w] path 显示一个节点的统计/元数据。
  •         sync path 

在leader和follower之间同步一个节点的数据(异步同步)sync /

  •         version 版本

3. 构建zookeeper集群

为了获得可靠的 ZooKeeper 服务,您应该将 ZooKeeper 部署在一个称为ensemble的集群中。只要大多数合奏都已启动,该服务就可用。因为 Zookeeper 需要多数,所以最好使用奇数台机器。比如有四台机器的ZooKeeper只能处理一台机器的故障;如果两台机器出现故障,剩下的两台机器不构成多数。然而,有了五台机器,ZooKeeper 可以处理两台机器的故障。

server.x=[hostname]:nnnnn[:nnnnn] 等:(无 Java 系统属性)组成 ZooKeeper 集合的服务器。当服务器启动时,它通过在数据目录中查找文件myid来确定它是哪个服务器。该文件包含了服务器数量,在ASCII,它应该与Xserver.x在此设置的左侧。客户端使用的组成 ZooKeeper 服务器的服务器列表必须与每个 ZooKeeper 服务器拥有的 ZooKeeper 服务器列表相匹配。

有两个端口号nnnnn。第一个follower用于连接leader,第二个用于leader选举。如果你想在一台机器上测试多台服务器,那么每台服务器可以使用不同的端口。

从 ZooKeeper 3.6.0 开始,可以为每个 ZooKeeper 服务器指定多个地址(参见ZOOKEEPER-3188)。要启用此功能,您必须将multiAddress.enabled配置属性设置为true。这有助于提高可用性并为 ZooKeeper 添加网络级别的弹性。当服务器使用多个物理网络接口时,ZooKeeper 能够绑定所有接口,并在网络错误的情况下运行时切换到工作接口。可以使用管道 ('|') 字符在配置中指定不同的地址。使用多个地址的有效配置如下所示:

server.1=zoo1-net1:2888:3888|zoo1-net2:2889:3889
server.2=zoo2-net1:2888:3888|zoo2-net2:2889:3889
server.3=zoo3-net1:2888:3888|zoo3-net2:2889:3889

windows下集群

1. 配置conf

复制4个cfg文件,其实3个就够,强烈推荐基数台。这里我是配置了4个,这个不重要。如果想在同一台机器上进行模拟,由于ip都是localhost,所以建议修改端口号。如果是在不同的机器上,由于ip不同,端口号可以相同。反正注意一下这个事。

2. 复制4个启动脚本

在启动脚本中指定一下启动时需要的配置。

3. 根据cfg中配置的dataDir、dataLogDir两个地址去创建目录

并且需要再dataDir目录下创建一个myid的文件,每个服务对应一个dataDir目录,将节点编号配置到myid文件中。

4. paxos

这里可能一下在不太懂,可以先继续往下学习,返回来在看这个,就明白了

先说Paxos,它是一个基于消息传递的一致性算法,Leslie Lamport在1990年提出,近几年被广泛应用于分布式计算中,Google的Chubby,Apache的Zookeeper都是基于它的理论来实现的,Paxos还被认为是到目前为止唯一的分布式一致性算法,其它的算法都是Paxos的改进或简化。有个问题要提一下,Paxos有一个前提:没有拜占庭将军问题。就是说Paxos只有在一个可信的计算环境中才能成立,这个环境是不会被入侵所破坏的。

关于Paxos的具体描述可以在Wiki中找到:http://zh.wikipedia.org/zh-cn/Paxos算法。网上关于Paxos分析的文章也很多。这里希望用最简单的方式加以描述并建立起Paxos和ZK Server的对应关系。

Paxos描述了这样一个场景,有一个叫做Paxos的小岛(Island)上面住了一批居民,岛上面所有的事情由一些特殊的人决定,他们叫做议员(Senator)。议员的总数(Senator Count)是确定的,不能更改。岛上每次环境事务的变更都需要通过一个提议(Proposal),每个提议都有一个编号(PID),这个编号是一直增长的,不能倒退。每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生效。每个议员只会同意大于当前编号的提议,包括已生效的和未生效的。如果议员收到小于等于当前编号的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上面记录的编号,他不断更新这个编号。整个议会不能保证所有议员记事本上的编号总是相同的。现在议会有一个目标:保证所有的议员对于提议都能达成一致的看法。

好,现在议会开始运作,所有议员一开始记事本上面记录的编号都是0。有一个议员发了一个提议:将电费设定为1元/度。他首先看了一下记事本,嗯,当前提议编号是0,那么我的这个提议的编号就是1,于是他给所有议员发消息:1号提议,设定电费1元/度。其他议员收到消息以后查了一下记事本,哦,当前提议编号是0,这个提议可接受,于是他记录下这个提议并回复:我接受你的1号提议,同时他在记事本上记录:当前提议编号为1。发起提议的议员收到了超过半数的回复,立即给所有人发通知:1号提议生效!收到的议员会修改他的记事本,将1好提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法令并告诉对方:1元/度。

现在看冲突的解决:假设总共有三个议员S1-S3,S1和S2同时发起了一个提议:1号提议,设定电费。S1想设为1元/度, S2想设为2元/度。结果S3先收到了S1的提议,于是他做了和前面同样的操作。紧接着他又收到了S2的提议,结果他一查记事本,咦,这个提议的编号小于等于我的当前编号1,于是他拒绝了这个提议:对不起,这个提议先前提过了。于是S2的提议被拒绝,S1正式发布了提议: 1号提议生效。S2向S1或者S3打听并更新了1号法令的内容,然后他可以选择继续发起2号提议。

好,我觉得Paxos的精华就这么多内容。现在让我们来对号入座,看看在ZK Server里面Paxos是如何得以贯彻实施的。

小岛(Island)——ZK Server Cluster

议员(Senator)——ZK Server

提议(Proposal)——ZNode Change(Create/Delete/SetData…)

提议编号(PID)——Zxid(ZooKeeper Transaction Id)

正式法令——所有ZNode及其数据

貌似关键的概念都能一一对应上,但是等一下,Paxos岛上的议员应该是人人平等的吧,而ZK Server好像有一个Leader的概念。没错,其实Leader的概念也应该属于Paxos范畴的。如果议员人人平等,在某种情况下会由于提议的冲突而产生一个“活锁”(所谓活锁我的理解是大家都没有死,都在动,但是一直解决不了冲突问题)。Paxos的作者Lamport在他的文章”The Part-Time Parliament“中阐述了这个问题并给出了解决方案——在所有议员中设立一个总统,只有总统有权发出提议,如果议员有自己的提议,必须发给总统并由总统来提出。好,我们又多了一个角色:总统。

总统——ZK Server Leader

又一个问题产生了,总统怎么选出来的?oh, my god! It’s a long story. 在淘宝核心系统团队的Blog上面有一篇文章是介绍如何选出总统的,有兴趣的可以去看看:http://rdc.taobao.com/blog/cs/?p=162

现在我们假设总统已经选好了,下面看看ZK Server是怎么实施的。

情况一:

屁民甲(Client)到某个议员(ZK Server)那里询问(Get)某条法令的情况(ZNode的数据),议员毫不犹豫的拿出他的记事本(local storage),查阅法令并告诉他结果,同时声明:我的数据不一定是最新的。你想要最新的数据?没问题,等着,等我找总统Sync一下再告诉你。

情况二:

屁民乙(Client)到某个议员(ZK Server)那里要求政府归还欠他的一万元钱,议员让他在办公室等着,自己将问题反映给了总统,总统询问所有议员的意见,多数议员表示欠屁民的钱一定要还,于是总统发表声明,从国库中拿出一万元还债,国库总资产由100万变成99万。屁民乙拿到钱回去了(Client函数返回)。

情况三:

总统突然挂了,议员接二连三的发现联系不上总统,于是各自发表声明,推选新的总统,总统大选期间政府停业,拒绝屁民的请求。

呵呵,到此为止吧,当然还有很多其他的情况,但这些情况总是能在Paxos的算法中找到原型并加以解决。这也正是我们认为Paxos是Zookeeper的灵魂的原因。当然ZK Server还有很多属于自己特性的东西:Session, Watcher,Version等等等等,需要我们花更多的时间去研究和学习。

 

 

 

5. ZAB 协议

ZAP  ,z是zookeeper ,a是 原子性, b是广播性

ZAB 协议是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复的一致性协议。基于该协议,ZooKeeper 实现了一种主从模式的系统架构来保持集群中各个副本之间的数据一致性。

原子:只有成功和是失败,没有中间状态

广播:分布式多节点,进行两两通信,将自己能的节点信息广播给其他节点。(过半,最终一致性

5.1 ZAB选主

选主依据:

1. election epoch, Zxid中的纪元(epoch),谁新优先选谁

2. zxid  Zxid的事务编号,谁新优先选谁。谁的Zxid编号越大,表示版本最新,数据最新

3. myid 节点编号,谁新优先选谁

 

选主过程

场景一,首次启动的时候

,首次启动的时候,Zxid都为0,所以会按照sid选主。

假设

A 节点,sid1

B 节点,sid=2

C节点,sid=3

D节点,sid=4

这种情况,由于是4个节点,需要(4/2)+1个节点同一,三个节点就可以选出leader

所以需要看启动顺序,如果先启动A B C,最后启动D,则C是leader

如果先启动A B D,最后启动C,则D是leader

 

场景二,leader挂掉,follower选主

如果原先D节点为leader,结果D挂掉了。由其他三个节点选取leader。过半的话,需要三台都同意

A发起投票

B发起投票

C发起投票

结论:最终3个节点都选择了C,并且每个节点都知道其他节点的选择。,过半的节点选择了C节点,所以C就是新leader

6. watch机制

6.1 特征

 ZooKeeper 中的所有读取操作 - getData()getChildren()exists() - 都可以选择将监视设置为副作用。以下是 ZooKeeper 对 watch 的定义:watch 事件是一次性触发器,发送到设置 watch 的客户端,当设置 watch 的数据发生变化时发生。在对手表的定义中,需要考虑三个关键点:

  • 一次性触发 ,watcher是一次性的,就是说当触发了watcher事件后,这个watcher就不存在了,下次变更就不会再次触发watcher事件。所以需要重新注册watcher,

    3.6.0 中的新功能:客户端还可以在 znode 上设置永久的递归监​​视,这些监视在触发时不会被删除,并且会以递归方式触发注册的 znode 以及任何子 znode 上的更改。

     

  • 发送到客户端,意思是,第一次修改数据触发watcher事件,当事件正在返回客户端,第二次数据修改也触发了这个事件,这种情况,zk中会维护一个队列,能够保证这些变更产生的watcher事件有序的返回到客户端。

  • watcher设置的数据这是指节点可以改变的不同方式。将 ZooKeeper 视为维护两个监视列表会有所帮助:数据监视和子监视。

  • getData() 和 exists() 设置数据监视。

  • getChildren() 设置子手表。或者,考虑根据返回的数据类型设置手表可能会有所帮助。getData() 和 exists() 返回有关节点数据的信息,而 getChildren() 返回子节点列表。因此, setData() 将触发正在设置的 znode 的数据监视(假设设置成功)。成功的 create() 将触发正在创建的 znode 的数据观察和父 znode 的子观察。成功的 delete() 将同时触发数据观察和子观察(因为不能再有子节点)被删除的 znode 以及父 znode 的子观察。

Watches 在客户端连接到的 ZooKeeper 服务器上本地维护。这允许手表在设置、维护和调度方面是轻量级的。当客户端连接到新服务器时,任何会话事件都会触发监视。与服务器断开连接时将不会收到手表。当客户端重新连接时,如果需要,任何先前注册的手表将被重新注册和触发。一般来说,这一切都是透明的。有一种情况可能会丢失监视:如果在断开连接时创建和删除 znode,则会丢失尚未创建的 znode 存在的监视。

6.2 watch的使用方式

我们可以使用三个读取 ZooKeeper 状态的调用来设置监视:exists、getData 和 getChildren。以下列表详细说明了监视可以触发的事件以及启用它们的调用:

  • Created 事件:通过调用exists 启用。
  • Deleted 事件:通过调用exists、getData 和getChildren 启用。
  • set事件:通过调用exists 和getData 启用。
  • children事件:通过调用 getChildren 启用。

6.3 持久的、递归的手表

标准手表是一次性触发器;如果您收到一个 watch 事件,并且希望收到有关未来更改的通知,则必须设置另一个 watch。

但是,因为标准手表是一次性触发器,并且在获取事件和发送新请求以获取手表之间存在延迟,所以您无法可靠地看到 ZooKeeper 中节点发生的每一个变化。准备好处理 znode 在获取事件和再次设置 watch 之间多次更改的情况。

举个例子:在触发了第一次watcher,调用process方法,此时watcher已经不存在了,是一次性的,但是,在重新设置watcher之前,该路径/myHello02 有发生变化,此时正处于第一个watcher失效,新watcher没有设置之前,这种情况就无法监控了。可能这个有个容忍性,但是需要注意这个点

标准watch:

设置一个标准watcher

1. 创建path   /aaaa

2. 通过get 设置 标准watcher

3. 修改数据为 bbbb

此时会触发watcher事件

4. 再次修改数据为 cccc,此时不能够触发事件,标准watcher是一次性的。

5. 重新设置watcher 

6. 再次修改数据dddd,还是可以触发事件的。但是在重新设置之前如果有其他的客户操作了/aaaa, 则不会被监控到

 

所以,3.6.0 中的新功能:现在在上述标准手表上有一个变体,您可以设置一个在触发时不会被移除的手表。此外,这些监视会触发事件类型NodeCreatedNodeDeletedNodeDataChanged ,并且可以选择递归地针对所有从监视注册的 znode 开始的 znode。

使用addWatch方法设置持久监视。触发语义和保证(一次性触发除外)与标准手表相同。两种模式:永久  永久_递归

 addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE

add watch /a 默认为一个持久递归类型、  add -m PERSISTENT/a 仅持久

NodeCreatedNodeDeletedNodeDataChanged 都会触发事件。

 

 

可以使用removewath来删这个持久监控watcher

区别:两种持久化watch的区别:

PERSISTENT, 操作和标准watch一致。只是持久化,就是触发后不会被删除。

PERSISTENT_RECURSIVE,若客户端设置了PERSISTENT_RECURSIVE模式的Watch,那么所有节点都会进行递归操作,而该watch会被触发事件的只有当被绑定的节点的内容被更新或其子节点的创建、删除、内容更新。【但NodeChildrenChanged事件不会触发到该watch】;

6.4  watch事件分类

  • 创建节点

触发当前节点的NodeCreated事件
触发当前节点的父节点的NodeChildrenChanged事件

  • 删除节点

触发当前节点的NodeDeleted事件
触发当前节点的父节点的NodeChildrenChanged事件

  • 修改节点

触发当前节点的NodeDataChanged事件

7. ZooKeeper 会话

ZooKeeper 客户端通过使用语言绑定创建服务句柄来建立与 ZooKeeper 服务的会话。

状态:stat

创建后,句柄以 CONNECTING 状态开始,客户端库尝试连接到构成 ZooKeeper 服务的服务器之一,此时它切换到 CONNECTED 状态,在正常操作期间,客户端句柄将处于这两种状态之一。

如果发生不可恢复的错误,例如会话过期或身份验证失败,或者如果应用程序明确关闭句柄,则句柄将移动到 CLOSED 状态。

 

创建会话需要的要素:

1. 包含逗号分隔的主机:端口对列表的连接字符串,每个对应于一个 ZooKeeper 服务器(例如“127.0.0.1:4545”或“127.0.0.1:3000,127.0.0.1 :3001,127.0.0.1:3002")

在 3.2.0 中添加:可选的“chroot”后缀也可以附加到连接字符串127.0.0.1:4545/app/a”或“127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a。这样相当于将/app/a当做根目录。场景用途:例如,一个Zookeeper集群被多个系统使用,不同系统可以建立不同系统的目录。

当客户端获得 ZooKeeper 服务的句柄时,ZooKeeper 会创建一个 ZooKeeper 会话,表示为一个 64 位数字,并将其分配给客户端。如果客户端连接到不同的 ZooKeeper 服务器,它将发送会话 ID 作为连接握手的一部分。作为一种安全措施,服务器为 session id 创建一个密码,任何 ZooKeeper 服务器都可以验证该密码。当客户端建立会话时,密码将与 session id 一起发送到客户端。每当客户端与新服务器重新建立会话时,客户端都会发送带有会话 ID 的密码。

2. 会话超时时间:用于创建 ZooKeeper 会话的 ZooKeeper 客户端库调用的参数之一是以毫秒为单位的会话超时。客户端发送请求的超时,服务器以它可以给客户端的超时响应。当前的实现要求超时时间至少是tickTime 的2 倍(在服务器配置中设置),最大是tickTime 的20 倍。ZooKeeper 客户端 API 允许访问协商超时

当客户端(会话)从 ZK 服务集群分区时,它将开始搜索在会话创建期间指定的服务器列表。最终,当客户端和至少一台服务器之间的连接重新建立时,会话将再次转换为“已连接”状态(如果在会话超时值内重新连接)或将转换为“过期”状态(如果在会话超时后重新连接)。不建议为断开连接创建新的会话对象(新的 ZooKeeper.class 或 c 绑定中的 zookeeper 句柄)。ZK 客户端库将为您处理重新连接。特别是我们在客户端库中内置了启发式方法来处理诸如“羊群效应”之类的事情......

会话过期由 ZooKeeper 集群本身管理,而不是由客户端管理。当 ZK 客户端与集群建立会话时,它会提供上面详述的“超时”值。集群使用此值来确定客户端的会话何时到期。当集群在指定的会话超时期限内没有收到来自客户端的消息(即没有心跳)时,就会发生过期。在会话到期时,集群将删除该会话拥有的任何/所有临时节点,并立即将更改通知任何/所有连接的客户端(任何监视这些 znode 的人)。此时,过期会话的客户端仍然与集群断开连接,直到/除非它能够重新建立与集群的连接,否则不会通知会话过期。

3.观察者: ZooKeeper 会话建立调用的另一个参数是默认观察者。当客户端发生任何状态更改时,会通知观察者。例如,如果客户端失去与服务器的连接,客户端将收到通知,或者如果客户端的会话过期等......这个观察者应该考虑断开连接的初始状态(即在任何状态更改事件被发送给观察者之前)客户端库)。在新连接的情况下,发送给观察者的第一个事件通常是会话连接事件。

会话通过客户端发送的请求保持活动状态。如果会话空闲的时间会导致会话超时,客户端将发送 PING 请求以保持会话活动。这个 PING 请求不仅允许 ZooKeeper 服务器知道客户端仍然处于活动状态,而且还允许客户端验证其与 ZooKeeper 服务器的连接是否仍然处于活动状态。PING 的时间足够保守,以确保有合理的时间来检测死连接并重新连接到新服务器。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值