zookeeper入门

本文深入介绍了Zookeeper,一个开源的分布式协调服务,详细阐述了其概念、特性、主要目录结构、配置、数据模型、作用、命令行操作、Watcher机制、ACL权限控制以及集群搭建。还探讨了Zookeeper的Java客户端,包括原生API的不足和Apache Curator的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Zookeeper

一、概念

是一个开放源代码的分布式协调服务,由知名互联网公司雅虎创建。设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构建成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

zookeeper是一个典型的分布式一致性解决方案,分布式应用系统可以基于它实现诸如数据发布/订阅,负载均衡,命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。Zookeeper可以保证如下分布式一致性特性。
在这里插入图片描述

二、zookeeper特性

  • 一致性:数据一致性,数据按照顺序分批入库
  • 原子性:事务要么成功要么失败,不会局部化
  • 单一视图:客户端连接集群中的任一zk节点,数据都是一致的
  • 可靠性:每次对zk的操作状态都会保存在服务端
  • 实时性:客户端最终可以读取到zk服务端的最新数据(一定时间段内)

三、Zookeeper主要目录结构

  • bin:主要的一些运行命令
  • conf:存放配置文件,其中需要修改zoo.cfg(zoo_sample.cfg)
  • contrib:附加的一些功能
  • dist-manven:mvn编译后的目录(包含一些jar包和pomw文件)
  • docs:文档
  • lib:平时开发所需要依赖的jar包(在后续开发java客户端的时候用到)
  • recipes:经典案例demo代码(包括lock锁和队列等)
  • src:源码

四、zoo.cfg配置

从zoo_sample.cfg拷贝一份新的zoo.cfg放在同一个目录下。

  • tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳,ZooKeeper使用的基本时间单位(以毫秒为单位)。
  • dataDir:Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • dataLogDir:Zookeeper 保存日志文件的目录
  • clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
windows环境下:
dataDir=D:\common\zookeeper-3.4.14\zookeeper-3.4.14\dataDir
dataLogDir=D:\common\zookeeper-3.4.14\zookeeper-3.4.14\dataLog
linux环境下:
dataDir=/usr/local/zookeeper/zookeeper-3.4.14/dataDir
dataLogDir=/usr/local/zookeeper/zookeeper-3.4.14/dataLogDir

五、 Zookeeper的基本数据模型介绍

  • 是一个树形结构
  • 每一个节点都成为znode,它可以有子节点,也可以有数据
  • 每个节点还可以分为临时节点(seesion失效数据丢失)和永久节点(session失效数据不丢失),临时节点在客户端断开后消失
  • 每个节点都有各自的版本号,可以通过命令行来显示节点信息
  • 每当节点的数据发生变化,那么该节点的版本号会累加(乐观锁)
  • 删除/修改过时节点,版本号不匹配会报错(当前节点已被别人修改过,不再匹配,也是使用乐观锁的思想)
  • 每个zk节点存储的数据不宜过大,几k即可
  • 节点可以设置权限acl,可以通过权限来限制用户的访问

六、Zookeeper作用

  • master节点选举,主节点挂了以后,从节点就会接手工作,并且保证这个节点是唯一的,这就是所谓的首脑模式,从而保证集群高可用

  • 统一配置文件管理:即只需要修改其中一台服务器的文件,就可以把相同配置的文件同步更新到其它所有服务器

  • 发布与订阅,类似消息队列MQ,dubbo发布者把数据存放到znode上,订阅者会读取这个数据

  • 提供分布式锁

  • 集群管理(主从数据同步),集群中保证数据强一致性

七、常用命令行操作

  • 在bin目录下通过 ./zkServer.sh start 启动zookeeper
  • 查看 zookeeper状态 ./zkServer.sh status
  • 通过 ./zkCli.sh 连接zk的客户端进入命令行后台
  • ls 命令

ls path [watch ] 指可以查看某一个节点下有哪些子节点列表,watch是一个监视器

[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /zookeeper
[quota]
[zk: localhost:2181(CONNECTED) 2] ls /zookeeper/quota
[]
[zk: localhost:2181(CONNECTED) 3] 

/ 就是根节点,zookeeper就是父节点, quota就是子节点

  • ls2 命令

ls2 path [watch ] 指查看当前节点的子节点和状态信息

[zk: localhost:2181(CONNECTED) 3] ls2 /
[zookeeper]    //当前节点的子节点
cZxid = 0x0    //Zookeeper为节点分配的Id
ctime = Wed Dec 31 19:00:00 EST 1969  //节点创建时间
mZxid = 0x0    //修改后的id
mtime = Wed Dec 31 19:00:00 EST 1969  //修改时间
pZxid = 0x0   //子节点id
cversion = -1   //子节点的version
dataVersion = 0  //当前节点数据版本
aclVersion = 0   //权限版本
ephemeralOwner = 0x0
dataLength = 0  // 数据长度
numChildren = 1  //子节点个数
  • stat 命令

stat path

stat只显示节点的状态信息,不显示当前节点的子节点
可以看出,ls2 = ls + stat

[zk: localhost:2181(CONNECTED) 4] stat /
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
  • get 命令

get path

将当前节点存储的数据提取出来(数据 不存在则为空)

[zk: localhost:2181(CONNECTED) 14] get /testzoo
nihaoa
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x2
mtime = Mon Apr 22 05:29:06 EDT 2019
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

  • create 命令

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

[zk: localhost:2181(CONNECTED) 10] create /testzoo nihaoa
Created /testzoo

当我们创建的时候在指令上加上 -e 我们会创建一个临时的节点

[zk: localhost:2181(CONNECTED) 17] create -e /testzoo/test nihaoa2
Created /testzoo/test
[zk: localhost:2181(CONNECTED) 18] get /testzoo
nihaoa
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x2
mtime = Mon Apr 22 05:29:06 EDT 2019
pZxid = 0x4
cversion = 1    //版本号+1了
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 1

会发现此时 节点 /testzoo 的 cversion=1 (版本号+1了)

[zk: localhost:2181(CONNECTED) 20] get /testzoo/test
nihaoa2
cZxid = 0x4
ctime = Mon Apr 22 05:36:20 EDT 2019
mZxid = 0x4
mtime = Mon Apr 22 05:36:20 EDT 2019
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x100000a70750000 //不再是OXO了,变化了
dataLength = 7
numChildren = 0

可以看到此时ephemeralOwner = 0x100000a70750000,不再是OXO了,说明这个节点是一个临时节点。

当我们创建的时候在指令上加上 -s 我们会创建一个顺序节点

[zk: localhost:2181(CONNECTED) 8] create -s  /testzoo/niuniuniu seq
Created /testzoo/niuniuniu0000000005
[zk: localhost:2181(CONNECTED) 9] create -s  /testzoo/niuniuniu seq
Created /testzoo/niuniuniu0000000006
[zk: localhost:2181(CONNECTED) 10] create -s  /testzoo/niuniuniu seq
Created /testzoo/niuniuniu0000000007
[zk: localhost:2181(CONNECTED) 11] create -s  /testzoo/niuniuniu seq
Created /testzoo/niuniuniu0000000008
[zk: localhost:2181(CONNECTED) 12] create -s  /testzoo/niuniuniu seq
Created /testzoo/niuniuniu0000000009

  • set 命令

set path data [version] 通过版本号修改某一节点的值

[zk: localhost:2181(CONNECTED) 26] set /testzoo  '测试一下'  2
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x1c
mtime = Mon Apr 22 05:58:59 EDT 2019
pZxid = 0x15
cversion = 11
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 9
[zk: localhost:2181(CONNECTED) 27] get /testzoo
测试一下
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x1c
mtime = Mon Apr 22 05:58:59 EDT 2019
pZxid = 0x15
cversion = 11
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 9
  • delete 命令

删除某个节点 如果不加版本号则会删除这个节点

[zk: localhost:2181(CONNECTED) 28] ls /testzoo
[zoooo, test, niuniuniu0000000009, niuniuniu0000000008, niuniuniu0000000007, momo, niuniuniu0000000006, niuniuniu0000000005, demo]
[zk: localhost:2181(CONNECTED) 29] delete /testzoo/niuniuniu0000000005
[zk: localhost:2181(CONNECTED) 30] delete /testzoo/niuniuniu0000000006
[zk: localhost:2181(CONNECTED) 31] delete /testzoo/niuniuniu0000000007
[zk: localhost:2181(CONNECTED) 32] delete /testzoo/niuniuniu0000000008
[zk: localhost:2181(CONNECTED) 33] ls /testzoo                        
[zoooo, test, niuniuniu0000000009, momo, demo]
[zk: localhost:2181(CONNECTED) 34] 

如果加上版本号只会去删除掉对应的版本号的节点数据,如果版本号不对应则报错版本号无效

[zk: localhost:2181(CONNECTED) 40] delete /testzoo/niuniuniu0000000009 0
version No is not valid : /testzoo/niuniuniu0000000009

八、zk特性-watcher机制

  • 针对每一个节点的操作都会有一个监督者 -> watcher
  • 当监控的某个节点(znode)发生增删改变化时都会触发一个watcher事件
  • zk中的watch是一次性的,触发后立即销毁
  • 针对不同类型的操作,触发的watch事件也是不同:
1.(子/父)节点创建事件
2.(子/父)节点删除事件
3.(子/父)节点修改事件

8.1 Watcher命令行学习

  • 通过get path [watch]设置watcher
[zk: localhost:2181(CONNECTED) 45] get /testzoo watch  
测试一下
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x1c
mtime = Mon Apr 22 05:58:59 EDT 2019
pZxid = 0x23
cversion = 16
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 4

给节点 /testzoo 设置一个监听器(监督者)

8.2 watcher事件类型

8.2.1 父节点watcher事件类型
  • 创建父节点触发:NodeCreated事件

stat /demozookeeper watch :给节点 /demozookeeper 设置一个监听器(监督者),当创建 /demozookeeper时,触发了watcher事件,事件类型是type:NodeCreated,path:/demozookee为此次watcher监听的节点。

[zk: localhost:2181(CONNECTED) 50] stat /demozookeeper  watch             
Node does not exist: /demozookee
[zk: localhost:2181(CONNECTED) 52] create /demozookee '你好世界'      

WATCHER::

WatchedEvent state:SyncConnected type:NodeCreated path:/demozookee
Created /demozookee
[zk: localhost:2181(CONNECTED) 53] 
  • 修改父节点数据触发:NodeDataChanged事件

给 /testzoo 设置一个监听器,当节点 /testzoo 修改时,触发了watcher事件,事件类型是type:NodeDataChanged,path:/testzoo为此次监听器watcher所监听的节点。

[zk: localhost:2181(CONNECTED) 45] get /testzoo watch
测试一下
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x1c
mtime = Mon Apr 22 05:58:59 EDT 2019
pZxid = 0x23
cversion = 16
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 4
[zk: localhost:2181(CONNECTED) 46] set /testzoo '你还好吗?'

WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/testzoo
cZxid = 0x2
ctime = Mon Apr 22 05:29:06 EDT 2019
mZxid = 0x24
mtime = Mon Apr 22 06:52:23 EDT 2019
pZxid = 0x23
cversion = 16
dataVersion = 4
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 15
numChildren = 4

  • 删除父节点触发:NodeDeleted

删除父节点 /demozookee 时触发 type:NodeDeleted 事件,path:/demozookee为此次监听器(watcher)所监听的节点。

[zk: localhost:2181(CONNECTED) 56] get /demozookee watch
啥啊?
cZxid = 0x27
ctime = Mon Apr 22 06:58:28 EDT 2019
mZxid = 0x28
mtime = Mon Apr 22 07:09:48 EDT 2019
pZxid = 0x27
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 0

[zk: localhost:2181(CONNECTED) 57] delete /demozookee

WATCHER::

WatchedEvent state:SyncConnected type:NodeDeleted path:/demozookee
8.2.2 watcher子节点事件类型
  • ls为父节点设置watcher(使用get命令为父节点设置watcher不会触发子节点创建事件),创建子节点触发:NodeChildrenChanged
[zk: localhost:2181(CONNECTED) 73] ls /testzoo watch              
[zoooo, test, momo, nodetest1, nodetest3, nodetest2, demo]
[zk: localhost:2181(CONNECTED) 74] create /testzoo/nodetest4 node4

WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testzoo
Created /testzoo/nodetest4
  • ls为父节点设置watcher(使用get命令为父节点设置watcher不会触发子节点创建事件),删除子节点触发:NodeChildrenChanged
[zk: localhost:2181(CONNECTED) 2] ls /testzoo watch
[test, nodetest4, nodetest1, nodetest3, nodetest2, demo]
[zk: localhost:2181(CONNECTED) 3] delete /testzoo/test

WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testzoo
  • ls为父节点设置watcher,修改子节点不触发事件(必须要把子节点当做父节点来设置watcher方可触发事件)
[zk: localhost:2181(CONNECTED) 4] ls /testzoo watch   
[nodetest4, nodetest1, nodetest3, nodetest2, demo]
[zk: localhost:2181(CONNECTED) 5] set /testzoo/nodetest2 jjjjjjj
cZxid = 0x2a
ctime = Mon Apr 22 21:31:37 EDT 2019
mZxid = 0x32
mtime = Mon Apr 22 21:52:17 EDT 2019
pZxid = 0x2a
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0

8.3 watcher使用场景

  • 进行统一资源配置

即更新主机上新的配置信息时,根据watcher事件,同步更新集群中所有客户端的配置信息。

  • 降级开关

比如秒杀等场景,当mq集群挂了的时候,此时可以用zookeeper的watcher做降级开关,生产者不再将消息写入mq集群,而去用降级服务(比如使用redis做的发布订阅功能)

九、ACL权限控制

  • 针对节点可以设置相关的读写等权限,目的是为了保障数据的安全性
  • 权限permissions可以指定不同的权限范围以及角色
  • getAcl:获取某个节点的acl权限信息
  • setAcl:设置某个节点的acl权限信息
  • addauth:新注册用户(密码是明文的,但是在zk系统里密码是以加密的形式存在的)或登录用户

9.1 ACL的构成

  • zk的acl通过[scheme?permission]来构成权限列表
  • scheme:代表采用的某种权限机制 (五种权限机制 一般常用的为四种)
  • id:代表允许访问的用户
  • permissions:权限组合的字符串
9.1.1 scheme
  • wolrd:world下只有一个id,即只有一个用户,也就是anyone,那么组合的写法就是 world:anyone:[permissions](即任何人都有权限访问这个节点)
  • auth:代表认证登录,即用户登录之后才有的权限,写法是auth:user:password:[peemissions]
  • digest:需要对密码加密才能访问,组合形式为digest:username:BASE64(SHA1(password)):[permissions]

其实,auth和digest的区别就是,前者明文,后者密文,而setAcl /path auth:lee:lee:cdrwa与setAcl /path auth:lee:BASE64(SHA1(lee)):cdrwa是等价的,通过addauth digest lee:lee 后都能操作指定节点的权限

  • ip:当设置为ip指定的ip地址,此时限制ip进行访问,比如ip:192.168.1.1:[permissions]
  • super:表示超级管理员,拥有所有的权限
9.1.2 permissions

权限字符串缩写 crdwa

  • c(CERATE):创建子节点
  • r(READ):获取节点/子节点
  • d(DELETE):删除子节点
  • w(WRITE):设置子节点
  • a(ADMIN):设置权限
9.1.3 ACL命令行的使用
9.1.3.1 world:anyone: cdrwa

(1)节点 /testzoo/demo 拥有的是默认权限(即所有增删改查权限)

[zk: localhost:2181(CONNECTED) 10] getAcl /testzoo/demo
'world,'anyone
: cdrwa

(2)权限不足,无法操作

创建 /testzoo/demo节点 的子节点 /testzoo/demo/momomo,并给 /testzoo/demo 节点重新授权 world:anyone:crwa

此时所有用户没有删除子节点的权限,当删除 /testzoo/demo 节点 的子节点 /testzoo/demo/momomo 时,会报异常 Authentication is not valid (身份验证无效)

[zk: localhost:2181(CONNECTED) 16] create /testzoo/demo/momomo '你好啊!'       
Created /testzoo/demo/momomo
[zk: localhost:2181(CONNECTED) 18] getAcl /testzoo/demo       
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 19] setAcl /testzoo/demo world:anyone:crwa
cZxid = 0x9
ctime = Mon Apr 22 05:49:36 EDT 2019
mZxid = 0x9
mtime = Mon Apr 22 05:49:36 EDT 2019
pZxid = 0x37
cversion = 3
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1
[zk: localhost:2181(CONNECTED) 20] getAcl /testzoo/demo
'world,'anyone
: crwa
[zk: localhost:2181(CONNECTED) 21] delete /testzoo/demo/momomo
Authentication is not valid : /testzoo/demo/momomo

我们给 /testzoo/demo 节点 重新授权 world:anyone:a

这时所有用户对当前节点只有设置权限的权限,没有查询当前节点信息的权限,也没有更改数据的权限,更没有操作子节点的权限。

[zk: localhost:2181(CONNECTED) 23] setAcl /testzoo/demo world:anyone:a
cZxid = 0x9
ctime = Mon Apr 22 05:49:36 EDT 2019
mZxid = 0x9
mtime = Mon Apr 22 05:49:36 EDT 2019
pZxid = 0x37
cversion = 3
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1
[zk: localhost:2181(CONNECTED) 24] getAcl /testzoo/demo     
'world,'anyone
: a
[zk: localhost:2181(CONNECTED) 25] ls2 /testzoo/demo
Authentication is not valid : /testzoo/demo
9.1.3.2 auth:user:pwd:cdrwa、digest:user:BASE64(SHA1(pwd)):cdrwa、addauth digest user:pwd

(1)setAcl /testzoo/demo auth:lee:lee:cdrwa: 我们对 /testzoo/demo 节点重新设置权限 auth:lee:lee:cdrwa,被告知 Acl is not valid : /testzoo/demo ,是因为用户没有注册,此时需要先注册用户

(2)addauth digest lee:lee: 注册用户lee

(3)setAcl /testzoo/demo auth:lee:lee:cdrwa: 重新设置权限,此时设置成功

(4)getAcl /testzoo/demo: 查询权限,发现用户的密码被加密了

[zk: localhost:2181(CONNECTED) 29] setAcl /testzoo/demo auth:lee:lee:cdrwa       
Acl is not valid : /testzoo/demo
[zk: localhost:2181(CONNECTED) 30] addauth digest lee:lee
[zk: localhost:2181(CONNECTED) 31] setAcl /testzoo/demo auth:lee:lee:cdrwa
cZxid = 0x9
ctime = Mon Apr 22 05:49:36 EDT 2019
mZxid = 0x9
mtime = Mon Apr 22 05:49:36 EDT 2019
pZxid = 0x37
cversion = 3
dataVersion = 0
aclVersion = 4
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1
[zk: localhost:2181(CONNECTED) 32] getAcl /testzoo/demo                   
'digest,'lee:MzFvWNvXCPbX2fkwvXZavrxqQGo=
: cdrwa

(5)create /testzoo/demo2: 创建一个新的节点/testzoo/demo2

(6)setAcl /testzoo/demo2digest:lee:MzFvWNvXCPbX2fkwvXZavrxqQGo=:cdraw: 给 /testzoo/demo2 节点 设置权限 digest:lee:MzFvWNvXCPbX2fkwvXZavrxqQGo=:cdraw

(7)getAcl /testzoo/demo2: 查询 /testzoo/demo2 节点的权限。

[zk: localhost:2181(CONNECTED) 37] create /testzoo/demo2 '啊哈哈'

WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testzoo
Created /testzoo/demo2
[zk: localhost:2181(CONNECTED) 41] setAcl /testzoo/demo2 digest:lee:MzFvWNvXCPbX2fkwvXZavrxqQGo=:cdraw
cZxid = 0x41
ctime = Tue Apr 23 02:16:51 EDT 2019
mZxid = 0x41
mtime = Tue Apr 23 02:16:51 EDT 2019
pZxid = 0x41
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 9
numChildren = 0
[zk: localhost:2181(CONNECTED) 42] getAcl /testzoo/demo2
'digest,'lee:MzFvWNvXCPbX2fkwvXZavrxqQGo=
: cdrwa
[zk: localhost:2181(CONNECTED) 43] 

digest与auth的区别一个密文,一个是明文,但是保存的时候都是密文的,他们是等价的。

9.1.3.3 ip:192.168.1.1:cdrwa

(1)create /testzoo/ip ipnnn:创建 /testzoo/ip 节点
(2)setAcl /testzoo/ip ip:192.168.1.1:cdrwa :给 /testzoo/ip 节点设置ip权限,只有ip:192.168.1.1的ip能够访问这个节点。

[zk: localhost:2181(CONNECTED) 43] create /testzoo/ip ipnnn
Created /testzoo/ip
[zk: localhost:2181(CONNECTED) 46] setAcl /testzoo/ip ip:192.168.1.1:cdrwa
cZxid = 0x43
ctime = Tue Apr 23 02:37:01 EDT 2019
mZxid = 0x43
mtime = Tue Apr 23 02:37:01 EDT 2019
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 20
numChildren = 0
[zk: localhost:2181(CONNECTED) 47] getAcl /testzoo/ip
Authentication is not valid : /testzoo/ip
[zk: localhost:2181(CONNECTED) 48] ls /testzoo/ip
Authentication is not valid : /testzoo/ip
[zk: localhost:2181(CONNECTED) 49] 
9.1.3.4 超级用户设置

(1)修改zkServer.sh增加super管理员

加入 "-Dzookeeper.DigestAuthenticationProvider.superDigest=admin:x1nq8J5GOJVPY6zgzhtTtA9izLc="

(2)重启 zkServer.sh

./zkServer.sh restart

(3)重新进入zk命令行后台,查看 /testzoo/demo2 的信息,报异常(Authentication is not valid),当登录 admin 超级用户后,查看再无任何权限问题。

[zk: localhost:2181(CONNECTED) 1] ls /testzoo/demo2
Authentication is not valid : /testzoo/demo2
[zk: localhost:2181(CONNECTED) 2] addauth digest admin:admin 
[zk: localhost:2181(CONNECTED) 3] ls /testzoo/demo2         
[]
[zk: localhost:2181(CONNECTED) 4] ls2 /testzoo/demo2
[]
cZxid = 0x41
ctime = Tue Apr 23 02:16:51 EDT 2019
mZxid = 0x41
mtime = Tue Apr 23 02:16:51 EDT 2019
pZxid = 0x41
cversion = 0
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 9
numChildren = 0

9.2 zookeeper四字命令

(1)Zookeeper通过自身简写命令来和服务器进行交互

(2)需要使用到nc命令,安装:yum install nc

(3)使用方法:echo stat(ruok/dump等命令) | nc localhost 2181

stat命令

查看zk的状态信息,以及是否mode(集群还是单机)

Mode: standalone,代表是单机的

[root@localhost /]# echo stat | nc localhost 2181
Zookeeper version: 3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf, built on 03/06/2019 16:18 GMT
Clients:
 /0:0:0:0:0:0:0:1:56582[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 0/0/5
Received: 133
Sent: 132
Connections: 1
Outstanding: 0
Zxid: 0x48
Mode: standalone    //代表是单机
Node count: 15
ruok命令

查看当前zkServer是否启动,返回imok则说明启动的

[root@localhost /]# echo ruok | nc localhost 2181
imok[root@localhost /]# 
dump命令

列出未经处理的会话和临时节点,可以看到当前未经处理的会话和临时节点都是0,因为没有连接客户端

[root@localhost /]# echo dump | nc localhost 2181
SessionTracker dump:
Session Sets (0):  //会话 0 
ephemeral nodes dump:
Sessions with Ephemerals (0): //节点 0
conf命令

查看服务器配置

[root@localhost /]# echo conf | nc localhost 2181
clientPort=2181
dataDir=/usr/local/zookeeper/zookeeper-3.4.14/dataDir/version-2
dataLogDir=/usr/local/zookeeper/zookeeper-3.4.14/dataLogDir/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=0

cons命令

展示连接到服务器的客户端信息

[root@localhost /]# echo cons | nc localhost 2181
 /0:0:0:0:0:0:0:1:56590[0](queued=0,recved=1,sent=0)

envi命令

查看zookeeper的环境变量

[root@localhost /]# echo envi | nc localhost 2181
Environment:
zookeeper.version=3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf, built on 03/06/2019 16:18 GMT
host.name=localhost
java.version=1.8.0_211
java.vendor=Oracle Corporation
java.home=/usr/local/java/jdk1.8.0_211/jre
java.class.path=/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/classes:/usr/local/zookeeper/zookeeper-3.4.14/bin/../build/classes:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/lib/*.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../build/lib/*.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-log4j12-1.7.25.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-api-1.7.25.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/netty-3.10.6.Final.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/log4j-1.2.17.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/audience-annotations-0.5.0.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-3.4.14.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/src/main/resources/lib/*.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../conf:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/classes:/usr/local/zookeeper/zookeeper-3.4.14/bin/../build/classes:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/target/lib/*.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../build/lib/*.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-log4j12-1.7.25.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/slf4j-api-1.7.25.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/netty-3.10.6.Final.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/log4j-1.2.17.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../lib/audience-annotations-0.5.0.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-3.4.14.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../zookeeper-server/src/main/resources/lib/*.jar:/usr/local/zookeeper/zookeeper-3.4.14/bin/../conf:/usr/local/java/jdk1.8.0_211/lib/
java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=<NA>
os.name=Linux
os.arch=amd64
os.version=3.10.0-693.el7.x86_64
user.name=root
user.home=/root
user.dir=/usr/local/zookeeper/zookeeper-3.4.14/bin
[root@localhost /]# 

mntr命令

查看zk的健康信息

[root@localhost /]# echo mntr | nc localhost 2181
zk_version	3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf, built on 03/06/2019 16:18 GMT
zk_avg_latency	0
zk_max_latency	5
zk_min_latency	0
zk_packets_received	139
zk_packets_sent	138
zk_num_alive_connections	1
zk_outstanding_requests	0
zk_server_state	standalone
zk_znode_count	15
zk_watch_count	0
zk_ephemerals_count	0
zk_approximate_data_size	291
zk_open_file_descriptor_count	27
zk_max_file_descriptor_count	4096
zk_fsync_threshold_exceed_count	0
[root@localhost /]# 
wchs命令

查看watch的信息

[root@localhost /]# echo wchs | nc localhost 2181
0 connections watching 0 paths
Total watches:0

十、zookeeper 集群搭建

  • zookeeper集群、主从节点、心跳机制(选举模式)
  • 需要注意:环境变量的配置,ip配置不同,端口号一般保持相同
  • 集群测试,选举测试

十一、常用的zk java客户端

  • zk原生api
  • zkclient
  • Apache curator(强烈推荐)

11.1 zk原生api的不足之处

  • 超时重连,不支持自动,需要手动操作
  • watch注册一次后失效
  • 不支持递归创建节点

11.2 Apache curator

  • Apache 开源项目
  • 解决watcher的注册一次就失效的问题(永久存在)
  • Api更加简单易用
  • 提供更多的解决方案,并且实现简单:比如 分布式锁
  • 提供常用的Zookeeper工具类
  • 编码风格更简洁

11.3 curator之nodeCache一次注册N次监听

		final NodeCache nodeCache = new NodeCache(cto.client, nodePath);
		// buildInitial : 初始化的时候获取node的值并且缓存
		nodeCache.start(true);
		if (nodeCache.getCurrentData() != null) {
			System.out.println("节点初始化数据为:" + new String(nodeCache.getCurrentData().getData()));
		} else {
			System.out.println("节点初始化数据为空...");
		}
		nodeCache.getListenable().addListener(new NodeCacheListener() {
			public void nodeChanged() throws Exception {
				if (nodeCache.getCurrentData() == null) {
					System.out.println("空");
					return;
				}
				String data = new String(nodeCache.getCurrentData().getData());
				System.out.println("节点路径:" + nodeCache.getCurrentData().getPath() + "数据:" + data);
			}
		});

11.4 Watcher统一配置

分布式环境中,可以通过zookeeper的watcher机制对集群环境中所有的节点做统一的更新(比如降级开关,如果mq集群挂了,触发开关进行降级,此时通过watcher机制同步通知到集群环境中所有应用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值