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

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

众所周知,协调服务很难做好。它们特别容易出现诸如竞争条件和死锁之类的错误。ZooKeeper 背后的动机是减轻分布式应用程序从头开始实现协调服务的责任。

ZooKeeper 允许分布式进程通过共享的分层命名空间相互协调,该命名空间的组织类似于标准文件系统。命名空间由数据寄存器组成——在 ZooKeeper 中称为 znodes——这些类似于文件和目录。与典型的为存储而设计的文件系统不同,ZooKeeper 数据保存在内存中,这意味着 ZooKeeper 可以实现高吞吐量和低延迟。

ZooKeeper 实现非常重视高性能、高可用、严格有序的访问。ZooKeeper 的性能方面意味着它可以用于大型分布式系统。可靠性方面使其不会成为单点故障。严格的排序意味着可以在客户端实现复杂的同步原语。

如下图所示,组成 ZooKeeper 服务的服务器必须相互了解(Server与Server之间默认通过2888端口进行通信)。它们维护内存中的状态image,以及持久存储事务日志和快照。只要大多数服务器可用,ZooKeeper 服务就可用。

客户端连接到单个 ZooKeeper 服务器。客户端维护一个 TCP 连接,通过它发送请求、获取响应、获取监视事件和发送心跳。如果与服务器的 TCP 连接中断,客户端将连接到不同的服务器。

ZooKeeper保证:

它的目标是成为构建更复杂服务(例如同步)的基础,因此它提供了一组保证。这些是:

  • Sequential Consistency(顺序一致性):来自客户端的更新将按发送顺序应用。
  • Atomicity(原子性):更新要么成功要么失败。
  • Single System Image(单一系统image):无论客户端连接到哪个服务器,它都会看到相同的服务 view。即使客户端故障转移到具有相同会话的不同服务器,客户端也永远不会看到系统的旧view。
  • Reliability(可靠性) :一旦一个update应用成功, 他将会一直存在直到客户端修改覆盖
  • Timeliness(及时性):系统的客户view保证在特定时间范围内是最新的。

简单的API:

  • create : 在树中的某个位置创建一个节点
  • delete : 删除一个节点
  • exists:测试节点是否存在于某个位置
  • get data : 从节点读取数据
  • set data :将数据写入节点
  • get children : 检索节点的子节点列表
  • sync : 同步数据,在leader和follower之间同步数据(数据的同步过程是异步执行的)

对于zookeeper有个大致的初步了解之后,我们来使用一些基本的命令来探索一下。

我是通过docker-compose搭建的单机zookeeper集群,所以本博客是基于Docker-compose部署单主机zookeeper集群 来做的实验。

docker部分

列出 Compose 应用中的各个容器。输出内容包括当前状态、容器运行的命令以及网络端口

 docker-compose ps

可以看到运行了三个zookeeper 容器

我们首先进去docker 容器内部,来进行一系列操作,我这里先进入zookeeper-1容器

docker exec -it zookeeper-1 /bin/bash

如下图所示,已进入容器

查看文件,进入bin文件夹,里面有一些脚本文件,对于我们目前重要的有zkCli.sh和zkServer.sh文件

zkServer.sh用于启动ZooKeeper服务(我们这里已经启动运行了)
zkCli.sh以客户端的方式连接ZooKeeper服务。

zkServer.sh

zkServer.sh

输入这个脚本文件,可以看到有很多参数

启动ZooKeeper服务

zkServer.sh start

启动失败,不过没有关系,在进入容器之前,这个服务就已经启动了,所以端口应该已经被占用了,由于容器里面没有安装netstat,所以我就不查看端口占用情况了,否则可以用如下命令来查看端口情况 (服务启动会占用如下三个端口)
1、2181:对client端提供服务的端口
2、3888:选举leader使用
3、2888:集群内机器通讯使用(Leader监听此端口)

netstat  -anp  |grep 2181


查看ZooKeeper服务的状态:

./zkServer.sh status

这个为follower节点

ZooKeeper 的版本号

zkServer.sh version


其他命令我就不一一展示了。

zKCli.sh

客户端用于连接服务端的脚本

使用zKCli.sh连接server, 连接本地的服务,所以为回环地址,端口号为2181

./zkCli.sh  -server 127.0.0.1:2181


如图所示,建立好了连接,我们根据以下内容来尝试一些命令

数据模型和分层命名空间,节点(Znode):

ZooKeeper 提供的命名空间很像标准文件系统的命名空间。名称是由斜杠 (/) 分隔的一系列路径元素。ZooKeeper 命名空间中的每个节点都由路径标识。

每个节点被称为Znode , 下面可以有子节点,同时Znode上可以保存数据,同时还会保存一系列元信息(但是不能保存很多的数据,因为Zookeeper是直接运行在内存里面的,官方说每个Znode最大能存1M的数据)。并且ZooKeeper 并非设计为通用数据库或大型数据存储。相反,它管理协调数据。这些数据以配置、状态信息、集合点等形式出现。各种形式的协调数据的一个共同特性是它们相对较小:以千字节为单位。ZooKeeper 客户端和服务器实现有健全性检查,以确保 znodes 的数据少于 1M,但数据应该比平均少得多。
存储在命名空间中每个 znode 的数据是原子读写的。读取获取与 znode 关联的所有数据字节,写入替换所有数据。每个节点都有一个访问控制列表 (ACL),它限制了谁可以做什么(就是哪些客户端有哪些权利对某一个Znode执行某些操作)。

Znode类型:

  • 持久:持久是默认的Znode类型,一旦创建就一直存在即使 ZooKeeper 集群宕机,直到将其删除。
  • 临时:通常可以用在一些特定的场景,如分布式锁释放、健康检查等。临时节点的生命周期是与 客户端会话(session) 绑定的,会话消失则节点消失 。并且,临时节点只能做叶子节点 ,不能创建子节点。
  • 持久顺序:在持久节点基础上增加顺序特性,在节点后面附加一个单调递增的计数器,此计数器对于父 znode 是唯一的。计数器的格式为 %010d——即 10 位数字,带有 0(零)填充(以这种方式格式化计数器以简化排序),如 /node1/app0000000001 、/node1/app0000000002
  • 临时顺序:同理,在临时节点的基础上增加顺序特性,这数字后缀的应用场景可以实现诸如分布式队列,分布式公平锁等。
  • 容器:容器Znode类型是 3.6.0新增的节点类型。容器 znode 可用于leader,lock 等方法。服务端启动后,会有一个单独的线程去扫描所有的容器Znode,当容器的最后一个子节点被删除时,该容器将成为未来某个时间点被服务器删除的候选对象。
    注意:鉴于这个属性,我们应该准备好获得KeeperException.NoNodeException。当在容器znode中创建子节点时,我们需要检查KeeperException.NoNodeException,并在它发生时重新创建容器znode。
  • TTL:TTL(time to live,存活时间,单位为秒,3.6.0新增节点类型),创建持久或 持久顺序 znode 时,您可以选择为 znode 设置以毫秒为单位的 TTL。如果在 TTL 内没有修改 znode 并且没有子节点,它将成为服务器在未来某个时间点删除的候选节点。
    注意:TTL 节点必须通过系统属性启用extendedTypesEnabled=true(在配置文件中添加这个语句即可),因为默认情况下它们是禁用的。如果在没有设置正确系统属性的情况下创建 TTL 节点,服务器将抛出 KeeperException.UnimplementedException。

每个Znode除了可以存储数据外,其本身还存储了数据节点相关的一些状态信息。
Znode的状态信息如下表所示:

状态信息 描述
cZxid 该节点被创建时的事务idZooKeeper中的每个改变都会产生一个全局唯一的zxid,通过它可确定更新操作的先后顺序
ctime 该节点被创建的时间
mZxid 该节点最后一次更新的事务id
mtime 该节点最后一次更新的时间
pZxid 该节点的子节点列表最后一次修改的事务id,只有子节点列表变更才会更新pZxid,子节点内容变更不会更新
cversion 子节点版本号,该节点的子节点变化时值就会增加1
dataVersion 节点数据版本号,节点创建时为0,每更新一次节点数据(不管内容有无变化)该版本号的值增加1
aclVersion 节点的ACL版本号
ephemeralOwner 创建该临时Znodesession id,如果是持久Znode,则ephemeralOwner0
dataLength 节点数据的长度
numChildren 当前节点的子节点个数

Time in ZooKeeper
ZooKeeper是怎么记录时间相关信息的

  • Zxid:ZooKeeper 状态的每个更改都会收到一个zxid(ZooKeeper 事务 ID)形式的标记。这将向 ZooKeeper公开所有更改的总顺序。每次更改都会有一个唯一的 zxid,如果 zxid1 小于 zxid2,则 zxid1 发生在 zxid2 之前。
  • 版本号 version numbers:对节点的每次更改都会导致该节点的版本号之一增加。三个版本号分别是 version(znode
    数据更改的次数)、cversion(znode 子节点的更改次数)和 aversion(znode 的 ACL 的更改次数)。
  • Ticks:当使用multi-server的 ZooKeeper 时,服务器使用 ticks 来定义status uploads、会话超时、连接超时等事件的时间。 tick 时间仅通过最小会话超时(2 倍的 tick time)间接暴露; 如果客户端请求的会话超时时间小于最小会话超时时间,服务器会告诉客户端会话超时时间实际上这个Session的超时时间还是最小会话超时时间(tick time 的2倍,最大会话时间为20倍)。(在下面Session的部分有讲)
  • 实时 real time :将时间戳放入 znode 创建和 znode 修改的 stat 结构中。

客户端命令:create、delete、deleteall、get、getAllChildrenNumber、getEphemerals、ls、set、stat、sync、setquota、listquota、delquota

我们首先查看根路径/ 下有哪些节点,如下图所示,有个zookeeper 节点,zookeeper节点下面还有两个节点,分别为config和quota
ls:列出Znode下的所有直接子节点,加上-s参数还可以获取Znode的状态信息,加上-w参数还可以在Znode上留下一次性Watcher(触发一次就会被移除),加上-R参数则是获取Znode的所有子节点(子孙节点)
zookeeper 节点类似于文件系统

默认有三个持久Znode(/zookeeper、/zookeeper/config和/zookeeper/quota)
zkCli.sh脚本连接服务端还可以指定Znode:

./zkCli.sh -timeout 5000 -server 127.0.0.1:2181/zookeeper

连接指定Znode连接之后,之后在客户端执行的命令都是基于该路径/zookeeper之下

create:该命令用于创建Znode(默认为持久Znode);-s参数表示创建顺序Znode、-e参数表示创建临时Znode、-c参数表示创建容器Znode、-t ttl参数表示创建TTL Znode、data参数表示该Znode需要存储的数据、acl参数表示该Znode的权限设置(下面会进行介绍)。 path 表示这个节点的路径标识

因为TTL 节点的特殊性,我们这里采用这个做尝试(这里会报错)

create -s -t 20000 /xt "hello xt"


结束当前连接CTRL-C
输入exit从当前容器中退出
在zookeeper的配置文件zoo.cfg中加入如下代码(请注意所有zookeeper的配置文件全要修改,我这里部署了三个zookeeper server,因为需要zookeeper 的三个server会同步,所以都要能创建TTL Znode)

extendedTypesEnabled=true

然后回到docker-compose.yml 所在的文件夹,重新启动docker-compose 部署的zookeeper 单机集群
Docker-compose部署单主机zookeeper集群
停止当前zookeeper容器集群的运行(要在docker-compose.yml 所在文件夹执行这个命令)

docker-compose stop

然后重启zookeeper容器集群

docker-compose restart

如果修改的配置文件没生效(根据后面能否创建TTL Znode来做判定,不过我这里通过restart是配置文件生效了的)
你可以试试如下两个命令

停止并删除运行中的 Compose 应用。它会删除容器和网络,但是不会删除卷和镜像。

docker-compose down

重新部署Compose 应用 ,-d 后台启动

docker-compose up -d

重新部署成功后
再次进入zookeeper-1 容器内部

docker exec -it zookeeper-1 /bin/bash

执行如下命令建立到服务端的连接

./bin/zkCli.sh  -server 127.0.0.1:2181

再次创建TTL 节点

create -s -t 20000 /xt "hello xt"

如图所示,过了时间TTL Znode便会被自动删除

create -s -t 20000 /zookeeper/xt "hello xt"

如下图所示,在zookeeper 节点下创建新节点,顺序标号会从0开始,说明编号是针对每个父节点而言的(每个父节点下面的顺序编号都是从0开始)

stat:获取Znode的状态信息,加上-w参数还可以在Znode上留下一次性Watcher(触发一次就会被移除)

ceshi 节点是我一开始在根节点下面创建的持久顺序Znode,信息如下

创建 容器Znode
容器Znode没有顺序和持久属性(如果容器Znode没有子节点会被定为被删除的候选对象)

create -c /xtContainer "hello container"



set: 设置Znode存储的数据,加上-s参数还可以获取Znode的状态信息,并且可以基于version设置Znode存储的数据,版本号对不上会报错
更新指定Znode的数据,dataVersion会自增
cversion:如果该节点的子节点变化时值就会增加1
aclVersion:节点的ACL版本号,同理

delete:该命令用于删除Znode,可以基于version删除Znode,如果指定的version与Znode当前的dataVersion不同,删除就不会成功,否则会成功删除该Znode,类似乐观锁。每当节点的数据发生变化,该节点的版本号dataVersion会累加,而删除,修改节点,version号不匹配会报错

delete如果不指定version(也就是不带 -v),可以直接删除该Znode
delete 不能删除有子节点的Znode,要使用deleteall

get:获取Znode存储的数据,加上-s参数还可以获取Znode的状态信息,加上-w参数还可以在Znode上留下一次性Watcher(触发一次就会被移除)。

getAllChildrenNumber:获取Znode的所有子节点(子孙节点)个数
getEphemerals: 获取Znode的所有临时子节点(只能是直接临时子节点,因为临时节点不能有子节点)

sync:强制同步节点,这需要在ZooKeeper集群中使用,如果对节点数据的实时性要求很高,可以使用该命令。

setquota:设置节点的限额,节点个数(-n,所有子节点以及自身节点)和数据字节数(-b),quota不会起到实际的限制作用,超出了会打印WARN级别日志,限额一旦设置完成,只能删除再重新设置,setquota不能重置之前的限额。

create /test_setquota
setquota -n 2 /test_setquota
create /test_setquota/first
create /test_setquota/second
create /test_setquota/third
create /test_setquota/four
ls /test_setquota


zookeeper服务器会产生三类日志:事务日志、快照日志和log4j日志。
我这里查看事务日志,事务日志文件夹已经被我挂载到服务器的/datalog文件夹下面了
我使用zookeeper的日志读取脚本来读取事务日志(是被序列化的二进制文件,所以要用这个工具)

zkTxnLogToolkit.sh -d /datalog/version-2/log.1000000001

如下图所示,还是照常创建新子节点

我们只有再log4j的日志里面可以看到WARN级别的日志。
在很多别人的博客里面可以看到WARN日志,不过他们搭建zookeeper服务的方式和我不一样,我是用的docker-compose搭建的zookeeper集群,而他们使用手动安装启动。

我将log4j的日志文件输出到/logs下面,但是经过我后面实验,发现log4j的日志文件还是不能打印到这个文件夹下面,因为需要zookeeper 的zkServer.sh start来启动zookeeper服务,才会把log4j的日志文件打印到这个指定文件夹下面,原因还在他的启动脚本zkServer.sh上

然后再打印容器日志的里面也没能找到这些WARN日志(我使用的是3.7.0的zookeeper,这里我就先不深究了,如果有知道的大佬还烦请评论区踢我一下)

listquota:列出节点的配额信息(-1表示无限,即没有限制)
delquota:删除节点的配额,删除节点时并不会自动删除绑定在特定路径上的quota,需要手动删除。

Session(会话)

Session指的是ZooKeeper客户端与服务端的会话。客户端启动时,会与服务端建立一个TCP长连接,客户端需要通过心跳与服务端保持会话,也可以向服务端发送请求并接受响应,并且还可以接收来自服务端的事件通知(Watcher)。
使用zkCli.sh连接ZooKeeper服务:

./zkCli.sh -timeout 5000 -server 127.0.0.1:2181

timeout:表示ZooKeeper客户端向ZooKeeper服务端发送心跳的时间间隔,单位为毫秒。因为ZooKeeper客户端与ZooKeeper服务端的连接状态是通过心跳检测来维护的,如果在指定的时间间隔内,ZooKeeper客户端没有向ZooKeeper服务端发送心跳包,ZooKeeper服务端则会断开与该ZooKeeper客户端的连接。参数5000,单位为毫秒,表示ZooKeeper客户端向ZooKeeper服务端发送心跳的间隔为5秒。

server:指定ZooKeeper服务端的IP地址(这里是本地,所以是回环地址127.0.0.1)与客户端连接端口,ZooKeeper默认的客户端连接端口为2181


可以看到客服端 端口号为46428 ,服务端 端口号为2181 ,IP都是回环地址
还可以看到session id(全局唯一)和session timeout(单位毫秒)

在ZooKeeper中,客户端和服务端建立连接后,Session随之建立。由于 sessionID是 ZooKeeper 会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 的,因此,无论是哪台服务器为客户端分配的 sessionID,都务必保证全局唯一。

Session 有一个属性叫做:sessionTimeout ,sessionTimeout 代表会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。

服务端和客户端之间维持的是一个长连接(本质应该是tcp的长连接,可以减少tcp连接重复创建的开销,但是为了避免TCP连接将会越来越多,直到把服务器的TCP连接数量撑爆到上限,所以会设置一个过期时间),在session timeout时间内,服务端会确定客户端是否正常连接(客户端会定时向服务端发送心跳heart检测),。

这个session timeout并不是客户端可以随意设置的,客户端会把这个session timeout发送给服务端,服务端会返回一个它可以接受的session timeout给客户端(tickTime的[2, 20]倍是服务端可以接受的session timeout范围,tickTime是ZooKeeper中最小的时间单位长度 ,默认2000ms,因此服务端可以接受的session timeout范围默认是[4s, 40s])。
可以通过这个命令进行测试,设置之后服务端的session timeout 始终在[4s,40s].

./zkCli.sh -timeout 5000(自己随便填) -server 127.0.0.1:2181

Session状态转移如下图所示:

Session从NOT_CONNECTED状态开始,随着ZooKeeper客户端初始化,转移到CONNECTING状态(方向1)。 正常情况下,客户端会与服务端连接成功,并且转移到CONNECTED状态(方向2)。当客户端失去了与服务端的连接或者不能感知到服务端的存在,它会转移回CONNECTING(方向3),并且尝试寻找另一个ZooKeeper服务端。如果它能找到另一个服务端或者重新连接到之前的服务端,并确认了这个Session仍然有效(没有超时),它会转移回CONNECTED状态(方向2)。否则,它会定义这个Session失效,并转移到CLOSED(方向4)。客户端也可以主动关闭Session。(方向4和5)

客户端命令:quit、close、connect、history、redo

quit:直接离开客户端(停止了客户端程序),因此再次连接服务端需要重新运行zkCli.sh脚本

close:不会直接离开客户端,只是关闭与服务端的连接,执行该命令后Session状态会变成CLOSED,由于没有离开客户端,因此还可以使用connect命令重新连接服务端,但Session和之前的Session不是同一个了,session id会发生改变了,但session timeout还是保留了之前的配置(毕竟没有停止客户端程序)。

connect:该命令就是为了在没有离开客户端的情况下重新连接服务端,会先将当前的Session关闭再重新连接服务端。

history:该命令会列出在客户端中执行过的命令。(当前连接里面执行过的命令)
redo:重新执行history里面的命令。(指令标号与history里面的是对齐的)

ACL(访问控制列表)

ZooKeeper采用 ACL(Access Control Lists)策略来进行权限控制,类似于Linux文件系统的权限控制。
ACL权限控制,主要包括3个方面: 授权策略(Scheme)、授权对象(ID)以及授权权限(Permission)。ZooKeeper的权限控制是基于每个Znode的,需要对每个节点设置权限,每个Znode支持设置多种权限控制方案和多个权限,子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点。
授权策略(Scheme):

  • world:开放模式,world表示任意客户端都可以访问(默认设置)。
  • ip:限定客户端IP防问。
  • auth:只有在会话中通过了认证才可以访问(通过addauth命令)。
  • digest:与auth类似,区别在于auth用明文密码,而digest用SHA1+base64加密后的密码(通过addauth命令,实际场景中digest更常见)。

授权对象(ID)就是指定的授权策略(Scheme)的内容:
比如world:anyone中的anyone、
ip:191.124.2.131中的191.124.2.131、
auth:username:password中的username:password(明文密码)、digest:username:password_digest中的username:password_digest(用SHA1+base64加密后的密码)。

授权权限(Permission):

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

客户端命令:addauth、getAcl、setAcl

每个节点都有独立的ACL权限

  • addauth:添加认证用户。
  • getAcl:获取节点的ACL,加上-s参数还可以获取Znode的状态信息。
  • setAcl:设置节点的ACL,加上-s参数还可以获取Znode的状态信息,并且可以基于version设置Znode的ACL,加上-R参数(递归)可以将该节点和其所有子节点都设置成指定的ACL。

授权策略 digest

创建节点时不指定auth,该节点的ACL就是world:anyone:cdrwa。digest用SHA1+base64加密后的密码,这个加密后的密码可以用这条命令得到:echo -n xt:xt | openssl dgst -binary -sha1 | openssl base64(xt:xt表示username:password)。

echo -n xt:xt | openssl dgst -binary -sha1 | openssl base64



只分配了cdr权限,所以只能创建子节点,删除子节点(仅直接子节点)和读取节点数据及显示子节点列表
我再连接到另一个Zookeeper 的server试一下
给当前连接Session添加认证后才能拥有设置的cdr权限

授权策略 IP

zookeeper server所在网络的网关:192.168.64.1
我的zookeeper-1 server 的ip地址:192.168.64.3
zookeeper-2 server 的ip地址:192.168.64.2
zookeeper-3 server 的ip地址:192.168.64.4

我们设置只有192.168.64.3 的IP有cdrwa权限,我使用127.0.0.1向本地zookeeper server建立连接(与2181建立连接,本地发起的请求,发起ip为127.0.0.1回环地址),这里只是一个记录,大家不要跟着操作,只是做一个展示。

所以我们这里删除/test_aclIp这个节点,注意:d的删除权限是删除这个节点的子节点的权限,所以删除他自己还是可以的
然后添加本地的127.0.0.1的ip,使得他也具有cdrwa权限

在本地,对/test_aclIp是有操作权限的。我们看看192.168.64.3怎么样
那我现在Ctrl-C结束这个连接,然后再使用192.168.64.3的机器向任意一个zookeeper server建立连接(节点都是同步的,/test_aclIp已经同步到了其他zookeeper server,注意,我们创建节点的时候虽然是在follower进行的,但是会转发到leader进行处理,所有的写请求会转到leader处理,leader接收到请求会将请求封装成一个事务,并给这个事务分配一个全局递增的唯一ID,称为事务ID(ZXID),zookeeper 采用ZAB协议来保证分布式一致性,这里不多进行介绍了)

./bin/zkCli.sh -server 192.168.64.2:2181

如图所示,客户端为192.168.64.3:56756
服务端为192.168.64.2:2181

测试能否做cdrwa等操作(发现还是不行)

添加zookeeper 所在网络zookeeper-net的网关(192.168.64.1)

那这是为什么呢?
猜测:docker 所虚拟出来的zookeeper-net子网,里面所有的网络通信都会经过网关,由网关转发
那么我们先做一个实验,就是使用任意一个zookeeper-server机器连接任意一个zookeeper -server

经过实验证明,我所采用docker-compose搭建zookeeper集群的方式,
Docker-compose部署单主机zookeeper集群将他们统一放入zookeeper-net 子网中,在里面进行通信的时候会由网关代理(可是一个子网里面的机器为啥会用网关呢?不是跨子网的机器通信才会让网关进行转发吗?我想可能是因为我在使用docker-compose搭建网络集群的时候,使用的不是具体IP,而是使用的服务名)我这里自定义的桥接网络zookeeper-net会提供DNS解析,可以通过容器的名字或是别名访问其他容器.所以可能会通过网关来做一个中转。如果理解有误,还望大家批评指正。

Watcher(事件监听器)

Watcher是ZooKeeper很重要的特性。ZooKeeper允许用户在指定Znode注册 Watcher(绑定监听事件),当特定事件触发时(节点数据变更、节点删除、子节点状态变更等事件),ZooKeeper服务端会将事件通知到注册过该事件Watcher的客户端,该机制是ZooKeeper实现分布式协调服务的重要特性,通过这个事件机制,可以基于ZooKeeper实现分布式锁、集群管理等功能。

Watcher特性:比如当节点数据发生变化的时候,ZooKeeper会产生一个Watcher事件,并且会发送到客户端,客户端收到监听的节点事件后,就可以进行相应的业务处理了(可以实现发布与订阅)。ZooKeeper的Watcher机制,可以分为三个过程:客户端注册Watcher、服务端处理Watcher和客户端回调。

客户端命令:addWatch、printwatches、removewatches

  • addWatch:客户端在节点上添加监听,有两种模式PERSISTENT和PERSISTENT_RECURSIVE,PERSISTENT模式只监听指定的节点事件,而PERSISTENT_RECURSIVE模式会监听指定节点与它所有子节点的事件。
  • removewatches:删除客户端对节点的监听
  • printwatches:是否打印监听事件(on或者off)。

想了解更多命令的,可以输入help以查看

References:

  • https://blog.csdn.net/qq_37960603/article/details/121357613
  • https://blog.csdn.net/huangyuhuangyu/article/details/78220005
  • https://zookeeper.apache.org/doc/r3.6.2/zookeeperProgrammers.html#Data+Access
  • https://zookeeper.apache.org/doc/r3.6.2/zookeeperProgrammers.html#sc_zkDataModel_znodes
  • https://www.runoob.com/w3cnote/zookeeper-acl.html
  • http://t.zoukankan.com/linlf03-p-9866486.html
  • https://blog.csdn.net/dhaiuda/article/details/82820318

(写博客主要是对自己学习的归纳整理,资料大部分来源于书籍、网络资料和自己的实践,整理不易,但是难免有不足之处,如有错误,请大家评论区批评指正。同时感谢广大博主和广大作者辛苦整理出来的资源。)

Zookeeper 重要概念以及基本命令使用相关推荐

  1. 学习大数据的第47天(HDFS以及Zookeeper)——HDFS的重要架构知识点以及zookeeper的安装和基本命令

    学习大数据的第47天(HDFS以及Zookeeper)--HDFS的重要架构知识点以及zookeeper的安装和基本命令 HDFS的知识点 HDFS文件块的大小 HDFS的写流程 自己的话总结一下: ...

  2. ZooKeeper 基本概念:特点、数据模型、节点特性、Watcher、ACL

    文章目录 什么是ZooKeeper? 特点 设计目标 应用场景 系统模型 数据模型 节点特性 节点类型 节点状态 版本 Watcher ACL 权限模式:Scheme 权限对象:ID 权限:Permi ...

  3. Zookeeper基本概念

    引言 首先在学习Zookeeper之前,我们要知道Zookeeper是什么东西,其次我们要知道Zookeeper能干什么.我通过自己的总结和自己的理解和大家一起分享一下Zookeeper的基本的概念的 ...

  4. 一文带你了解Zookeeper基本概念、集群搭建、使用方法

    本文图文并茂的描述了:zookeeper是什么,演示了Zookeeper集群如何搭建.Zookeeper常用命令的使用.如何查看Zookeeper日志:详细描述了Zookeeper数据模型.watch ...

  5. 2018年第16周-ZooKeeper基本概念(配搭建过程和Master-Workers例子)

    背景 随着计算机的硬件和操作系统两者相辅相成地发展,从早期的ENIAC计算机到现在的x86的计算机,从以前的单一控制终端(Single Operator, Single Console, SOSC)的 ...

  6. 2019/08/09 zookeeper基础概念(01)

    **zookeeper主要是对分布式系统提供服务的,ES集群,分布式文件系统,mysql主从复制,主要不是工作同一节点的都称为分布式系统 分布式系统:是一个硬件或软件组件分布在网络中的不同的计算机之上 ...

  7. ZooKeeper基本概念总结

    目录 ZooKeeper 介绍 ZooKeeper 由来 ZooKeeper 概览 什么是分布式协调 ZooKeeper特点和语义保证 有哪些著名的开源项目用到了 ZooKeeper? ZooKeep ...

  8. Paxos分布式一致性算法简介和Apache ZooKeeper的概念映射

    为什么80%的码农都做不了架构师?>>>    Paxos是一个基于消息传递的一致性算法,近几年被广泛应用于分布式计算中,Google的Chubby,Apache的Zookeeper ...

  9. Zookeeper重要概念

    Zookeeper 第一章 Zookeeper基础 文章目录 Zookeeper 一.分布式特性 二.集群角色 三.Session 四.数据节点 五.Watcher 六.ACL 1. 权限模式:Sch ...

最新文章

  1. 用友公司Java面试题(含答案)
  2. Ubuntu在终端执行命令时出现的错误
  3. 9月——都已经9月了还不好好刷题?。。
  4. PyQt4布局管理——绝对定位方式
  5. python androidhelper怎么点击屏幕_python:如何模拟helper方法?
  6. 如何用Java创建不可变的Map
  7. IIS 启动不了(服务没有及时响应启动或控制请求)解决
  8. soidworks 生成PCD点云文件
  9. python进阶19垃圾回收GC
  10. 从零实现深度学习框架——优化反向传播相关代码
  11. Java求质数(素数)(超详细)
  12. 米家扫地机器人按键没反应_好到没理由不推荐 米家扫地机器人评测
  13. 三菱plc232数据线驱动下载_程序怎么上传下载?以西门子S7-200PLC为例为你讲解
  14. 一篇博客收能收录计算机网络?
  15. dns服务器异常不能上网怎么修复,DNS错误无法正常上网怎么办?
  16. 获取并解析心知天气数据
  17. Android api level对照表
  18. api系列聚美优品的知识点
  19. VirtualLab基础实验教程-7.偏振(2)
  20. IDEA项目中配置Maven镜像源(下载源)

热门文章

  1. 【 ListView --- ArrayAdapter】
  2. 马化腾称露露事件值得团队警醒 并打赏原作者200元
  3. Aski AI: 基于人工智能的在线AI工具平台
  4. 软件测试app内存溢出,检测APP内存溢出LeakCanary
  5. html5 onbeforeonload,window属性:onbeforeunload
  6. linux ftp服务器架设,linux ftp服务器架设配置教程
  7. Jetson nano 系统安装
  8. 如何提高小学生的阅读能力1
  9. Python OpenCV 批量修改文件夹内所有图片的尺寸
  10. 刷脸支付技术对接可以代理可以贴牌