zookeeper几个关键的东西

1.1 数据结构-节点 

  /a/b/c 节点 包含了目录和文件的特性(名称类似目录,本身又类似文件携带数据)

 

1.2 节点分类

  永久/临时|有序/无须

  特点一:节点的创建必须一级一级的创建,如创建/a/b节点,需要先创建/a节点,再创建/a/b节点

  特点二:节点的创建只能创建不存在的节点,不能重复,如已创建/a节点,再次创建/a节点会失败

  特点三:有序节点的创建为自动赋予序号,如创建/a,实际创建的是/a00000001,这个序号是递增的,再创建/b,实际创建的是/b0000002,再次创建/a,实际创建的是/a0000003(临时节点的创建可以多次创建/a,因为实际创建的是/a+序号,没有重复)

  特点四:每个节点都有版本号,新增时版本号为0,没有修改版本号递增

 

1.3 全局事务id

  zk集群中,所有的写操作,leader都会生成一个有序的事务id,事务的执行是按照事务id的顺序来执行的

 

1.4 watcher

  zk具有监控功能,可以监控节点的数据变化和节点删除,还可以监控子节点的增加和删除

 

1.5 zab协议

  leader选举、恢复同步、原子广播-----保证了zk集群数据的一致性

 

 

2 Zookeeper常用的业务场景

  zookeeper是一个分布式的数据一致性的解决方案。致力于为分布式应用一同一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调存储服务。

  维护配置信息

  分布式锁服务(临时有序节点)

  集群管理

  分布式唯一id(持久化有序节点)

 

2.1维护配置信息

  把zookeeper作为一个配置中心

  java编程经常会遇到配置项,比如数据库的url、schema、user和password等。通常这些配置项我们会放置在配置文件中,再将配置文件放置在服务器上当需要更改配置时,需要去服务器上修改对应的配置文件。但是随着分布式系统的兴起,由于许多服务都需要使用到该配置文件,因此有必须保证该配置服务的高可用性(highavailability)和各台服务器上配置数据的一致性。通常会将配置文件部署在一个集群上,然而一个集群动辄上千台服务器,此时如果再一台台服务器逐个修改配置文件那将是非常繁琐且危险的的操作,因此就需要一种服务,能够高效快速且可靠地完成配置项的更改等操作,并能够保证各配置项在每台服务器上的数据一致性。
  zookeeper就可以提供这样一种服务,其使用Zab这种一致性协议来保证一致性。现在有很多开源项目使用zookeeper来维护配置,比如在hbase中,客户端就是连接一zookeeper,获得必要的hbase集群的配置信息,然后才可以进一步操作。还有在开源的消息队列kafka中,也使用zookeeper来维护broker的信息。在alibaba开源的soa框架dubbo中也广泛的使用zookeeper管理一些配置来实现服务治理
 
2.2 分布式锁服务
  一个集群是一个分布式系统,由多台服务器组成。为了提高并发度和可靠性,多台服务器上运行着同一种服务。当多个服务在运行时就需要协调各服务的进度,有时候需要保证当某个服务在进行某个操作时,其他的服务都不能进行该操作,即对该操作进行加锁,如果当前机器挂掉后,释放锁并fail over 到其他的机器继续执行该服务
  zookeeper提供了临时有序节点,通过它生成分布式锁

 

2.3 集群管理

  一个集群有时会因为各种软硬件故障或者网络故障,出现某些服务器挂掉而被移除集群,而某些服务器加入到集群中的情况,zookeeper会将这些服务器加入/移出的情况通知给集群中的其他正常工作的服务器,以及时调整存储和计算等任务的分配和执行等。此外zookeeper还会对故障的服务器做出诊断并尝试修复
 
2.4 生成分布式唯一ID
  在过去的单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法在依靠数据库的
auto_increment属性来唯一标识一条记录了。此时我们就可以用zookeeper在分布式环境生成全局唯一ID。做法如下:每次要生成一个新Id时,创建一个持久顺序节点,创建操作返回的节点序号,即为新Id,然后把比自己节点小的删除即可

3 zookeeper的设计目标
  zooKeeper致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务
3.1 高性能
  zooKeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景
 
3.2 高可用
  zooKeeper一般以集群的方式对外提供服务,一般3 ~ 5台机器就可以组成一个可用的Zookeeper集群了,每台机器都会在内存中维护当前的服务器状态,并且每台机器之间相互保持着通信。只要集群中超过一半的机器都能够正常工作,那么整个集群就能够正常外服务
 
3.3严格顺序访问
  对于来自客户端的每个更新请求,ZooKeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序

4 zookeeper的数据模型
4.1 简介
  zookeeper的数据节点可以视为树状结构(或者目录),树中的各节点被称znode(即zookeeper node),一个znode可以有多个子节点。zookeeper节点在结构上表现为树状;使用路径path来定位某个znode,比如/ns-1/itcast/mysql/schema1/table1,此处ns-1、itcast、mysql、schema1、table1分别是根节点、2级节点、3级节点以及4级节点;其中ns-1是itcast的父节点,itcast是ns-1的子节点,itcast是mysql的父节点,mysql是itcast的子节点,以此类推。
  znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。
 
4.2 如何描述一个znode
  一个znode大体上分为3各部分
    1)节点的数据:即znode data(节点path, 节点data)的关系就像是java map中(key,value)的关系
    2)节点的子节点children
    3)节点的状态stat:用来描述当前节点的创建、修改记录,包括cZxid、ctime等
 
4.3 查看节点data、state
  节点状态stat的属性在zookeeper shell中使用get命令查看指定路径节点的data、stat信息
          [zk: localhost:2181(CONNECTED) 7] get /ns-1/tenant
      cZxid
= 0x6a0000000a       ctime = Wed Mar 27 09:56:44 CST 2019       mZxid = 0x6a0000000a       mtime = Wed Mar 27 09:56:44 CST 2019       pZxid = 0x6a0000000e       cversion = 2       dataVersion = 0       aclVersion = 0       ephemeralOwner = 0x0       dataLength = 0       numChildren = 2
  属性说明
  cZxid:数据节点创建时的事务 ID(zookeeper每一个写操作都会开启一个事务,而每个事务都会维护一个事务id。写操作包括节点创建、修改、删除)
  ctime:数据节点创建时的时间
  mZxid:数据节点最后一次更新时的事务 ID
  mtime:数据节点最后一次更新时的时间
  pZxid:数据节点的子节点最后一次被修改时的事务 ID
  cversion:子节点的更改次数
  dataVersion:节点数据的更改次数
  aclVersion:节点的 ACL 的更改次数(当前的节点的权限列表被修改的次数)
  ephemeralOwner:如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为 0
  dataLength:数据内容的长度(单位是字节)
  numChildren:数据节点当前的子节点个数

 

4.4 节点类型
  zookeeper中的节点有两种,分别为临时节点和永久节点。节点的类型在创建时即被确定,并且不能改变。
  临时节点(有序/无序):该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然可以也可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。
  持久化节点(有序/无序):该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除
  有序节点的特点是该节点会有一个序列号

5 zookeeper单机安装
5.1 zookeeper底层依赖于jdk
  zookeeper用户登录后,根目录下先进行jdk的安装,jdk
  使用jdk-8u131-linux-x64.tar.gz版本,上传并解压jdk
useradd zookeeper
passwd zookeeper//解压jdk
tar -xzvf jdk-8u131-linux-x64.tar.gz
 
5.2 配置jdk环境变量
// vim打开 .bash_profile文件
vi .bash_profile
// 文件中加入如下内容
JAVA_HOME=/home/zookeeper/jdk1.8.0_131
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
// 使环境变量生效
. .bash_profile
 
5.3 检测jdk安装
// 敲如下命令,系统如图反馈说明安装成功
java -version
 
5.4 zookeeper下载上传解压
5.4.1 下载
  下载地址:https://zookeeper.apache.org/releases.html#releasenotes
 
5.4.2 上传解压
// 解压zookeeper
tar -xzvf apache-zookeeper-3.6.2.tar.gz 

 

5.5 为zookeeper准备配置文件
// 进入conf目录 
cd /usr/local/programs/zookeeper/apache-zookeeper-3.6.2/conf

// 修改配置文件前先复制一份配置文件
cp zoo_sample.cfg zoo.cfg

// zookeeper根目录下新建data目录 -用于存放数据
  mkdir data

// vi 修改配置文件中的dataDir

// 此路径用于存储zookeeper中数据的内存快照、及事物日志文件
  dataDir=/usr/local/programs/zookeeper/apache-zookeeper-3.6.2/data

  配置文件名称改为 zoo.cfg

 

5.6 启动zookeeper
  进入bin目录 
  启动服务    ./zkServer.sh start
  客户端连接:./zkCli.sh

 

5.6 新版 ZooKeeper 启动时一直报错

  https://blog.csdn.net/peng2hui1314/article/details/107255142

 

5.6.1 错误

 Starting zookeeper … FAILED TO START

 

5.6.2 原因  

  1)下载的版本问题(>= 3.5.5)
  2)端口冲突问题(>=3.5.0)

5.7 下载的版本问题(>= 3.5.5)

  实际上只要 >= 3.5.5 版本都会出现这种问题。
  问题原因:下载了错误的版本文件,Zookeeper 从3.5.5后开始拆分为两个版本,而且他们的结构还很类似。
  标准版本(Apache ZooKeeper x.y.z ),下载的文件名为:apache-zookeeper-x.y.z-bin.tar.gz
  另一个是源码版本(Apache ZooKeeper x.y.z Source Release),下载的文件名为:apache-zookeeper-x.y.z.tar.gz
  所以下载 Zookeeper 的时候要注意,应该下载第一个。

5.8 端口冲突问题(可能遇到)
  在3.5.5版本及以上,Zookeeper 提供了一个内嵌的Jetty容器来运行 AdminServer,默认占用的是 8080端口,AdminServer 主要是来查看 Zookeeper 的一些状态,如果机器上有其他程序(比如:Tomcat)占用了 8080 端口,也会导致 Starting zookeeper … FAILED TO START 的问题。
  该问题的错误日志如下:

org.apache.zookeeper.server.admin.AdminServer$AdminServerException: Problem starting AdminServer on address 0.0.0.0, port 8080 and command URL /commands
        at org.apache.zookeeper.server.admin.JettyAdminServer.start(JettyAdminServer.java:176)
        at org.apache.zookeeper.server.ZooKeeperServerMain.runFromConfig(ZooKeeperServerMain.java:153)
        at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooKeeperServerMain.java:112)
        at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:67)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:140)
        at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:90)
Caused by: java.io.IOException: Failed to bind to /0.0.0.0:8080   //不能绑定8080端口
        at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:346)
        at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:307)
        at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
        at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:231)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
        at org.eclipse.jetty.server.Server.doStart(Server.java:385)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
        at org.apache.zookeeper.server.admin.JettyAdminServer.start(JettyAdminServer.java:167)
        ... 5 more
Caused by: java.net.BindException: Address already in use  //地址正在被使用
        at sun.nio.ch.Net.bind0(Native Method)
        at sun.nio.ch.Net.bind(Net.java:433)
        at sun.nio.ch.Net.bind(Net.java:425)
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
        at org.eclipse.jetty.server.ServerConnector.openAcceptChannel(ServerConnector.java:342)
        ... 12 more
Unable to start AdminServer, exiting abnormally
2020-07-17 21:07:30,759 [myid:] - INFO  [main:ZKAuditProvider@42] - ZooKeeper audit is disabled.
2020-07-17 21:07:30,760 [myid:] - ERROR [main:ServiceUtils@42] - Exiting JVM with code 4

  可以通过以下几种方式去解决
  1)如果不需要 AdminServer ,可以直接禁用:打开 zoo.cfg 配置文件,直接添加以下语句即可。

# 禁用 AdminServer 服务
admin.enableServer=false

  2)如果想使用 AdminServer , 那么可以直接在 zoo.cfg 配置文件中修改端口号即可,比如让其绑定 9000。

# admin port
admin.serverPort=9000

 

 

6 常用操作命令

6.1 基础命令

    ./zkServer.sh start  启动zookeeper

     ./zkServer.sh status  查看zookeeper状态

    ./zkCli.sh 启动客户端进入会话

    quit 结束当前会话-  也就是 ./zkCli.sh的会话结束了,需要重新./zkCli.sh新建会话

 

6.2 创建节点create 

6.2.1 格式

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

  格式:create [-s] [-e] path data acl 

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

 

6.2.2 创建持久化无序节点示例

  

  创建持久化有序节点,这里没有设置data,也就是null。有序节点的路径自动加上了一个序号

  

6.2.3 创建临时无序节点示例

  临时节点的生命周期是当前会话。quit退出当前会话的话,临时节点会被删除

  

      

      

  

 

6.3获取节点的数据get

6.3.1格式

  get path

 

6.3.2 获取无序节点示例

  

 

6.3.3获取有序节点示例

  它的路径自动加上了一个序号

  

 

6.4 查看节点状态信息stat

 

6.4.1 格式

  stat path [watch]

    path:代表路径。

    [watch]:对节点进行事件监听

 

6.4.2 示例

  

 

6.4.3 属性  

  节点各个属性如下表。其中一个重要的概念是 Zxid(ZooKeeper TransactionId-事务id),ZooKeeper 节点的每一次更改都具有唯一的 Zxid,且是递增的,如果 Zxid1 小于 Zxid2,则

Zxid1 的更改发生在 Zxid2 更改之前

  

  ACL是和当前节点的权限的相关的一个属性

 

6.5 修改节点存储的数据set

 

6.5.1 格式

  set path data [-v version] 

    path:节点路径

    data:需要存储的数据

    [version]:可选项,版本号(可用作乐观锁)。从创建一个节点开始,会为这个节点生成一个版本号,从0开始。每次对这个节点进行修改,版本号会+1

 

6.5.2  不加版本号示例

  

6.5.3 加上版本号示例

  通过stat命令,看到当前data版本号时7

  

   这里指定的版本号是15 所以修改失败

  

  这里指定的版本号是7 所以修改成功

  

 

6.6 删除节点delete

 

6.6.1 格式

  delete path [-v version]

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

 

6.6.2 示例

  当前data版本是8

  版本错误,删除失败

  

  版本正确,删除成功

  

  再创建一个节点 /hadop/a

  

  此时来删除/hadop,删除失败。也就是说,delete不能删除有子节点的节点

  

  

6.7 删除节点rmr(可删除带有子节点的节点)

  这个命令被deleteall替代,不推荐使用

6.7.1 格式

  rmr path

 

    path:节点路径

 

  

6.8 删除节点deleteall(可删除带有子节点的节点)

6.8.1 格式

  deleteall path     

    path:节点路径

 

 

6.8.2 示例

 

  

 

6.9 查看某个路径下目录列表ls

6.9.1 格式

  ls path

 

6.9.2 示例

  创建/a节点 创建/a/b节点

  

  查看a节点下的目录

  

   再创建节点/a/b/c  

  

  查看a节点下的目录,发现还是只有b节点。说明ls只能查看节点的子节点,不能查看子节点下的节点

  

 

6.10 查看某个路径下目录列表ls2

6.10.1 格式

  ls2 path

 

6.10.2 示例

  ls2命令和ls一样,也是查看节点的子节点,不能查看子节点下的节点,但是信息更加全面

  

  再创建一个节点/a/bb ls2查看

  

 

7.监听器

7.1 zookeeper 事件监听机制

7.1.1 watcher概念
  zookeeper提供了数据的发布/订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时(例如节点内容改变、节点下的子节点列表改变等),会实时、主动通知所有订阅者zookeeper采用了Watcher机制实现数据的发布/订阅功能。该机制在被订阅对象发生变化时会异步通知客户端,因此客户端不必在Watcher注册后轮询阻塞,从而减轻了客户端压力。watcher机制实际上与观察者模式类似,也可看作是一种观察者模式在分布式场景下的实现方式。

 

7.1.2 watcher架构
  Watcher实现由三个部分组成:Zookeeper服务端、Zookeeper客户端、客户端的ZKWatchManager对象
  客户端首先将Watcher注册到服务端,同时将Watcher对象保存到客户端的Watch管理器中。当ZooKeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch管理器会触发相关Watcher来回调相应处理逻辑,从而完成整体的数据发布/订阅流程

      

 

7.1.3 watch特性

     

  watch是串行化执行的,也就是一个一个的watch执行,串行同步执行。

 

7.2 watch相关命令

7.2.1 get

1)格式

  get path [watch] 或者  get [-s] [-w] path
  使用get path [watch] 注册的监听器能够在节点内容发生改变的时候,向客户端发出通知。需要注意的是 zookeeper 的触发器是一次性的 (One-time trigger),即触发一次后就会立即失效

 

2)示例

  开始监听get path [watch]

  

  另一个客户端修改

  

  此处收到事件通知

  

  开始监听get -w path

  

  另一个客户端修改

  

  此处收到事件通知

  

 

7.2.2 stat

1)格式

  stat path [watch] 或者 stat [-w] path

  使用stat path [watch] 注册的监听器能够在节点状态发生改变的时候,向客户端发出通知。需要注意的是 zookeeper 的触发器是一次性的 (One-time trigger),即触发一次后就会立即失效

 

2)示例

  开始监听stat path [watch]

  

  另一个客户端修改

  

  此处收到事件通知

  

  开始监听stat-w path

  

  另一个客户端修改

  

  此处收到事件通知

  

 

 

7.2.3 ls\ls2 path [watch]

1)格式

  ls\ls2 path [watch] 或者ls\ls2 -w path
  使用ls path [watch] 或ls2 path [watch] 注册的监听器能够监听该节点下所有子节点的增加和删除操作

 

2)示例

  

  

  

 

7.3 监听器的应用

  zookeeper可以作为配置中心来使用。监听器就可以对配置内容进行监听。当配置发生变化时,可以收到通知,做相应的处理。

 

8 ACL权限控制
8.1 概述
  zookeeper 类似文件系统,client 可以创建节点、更新节点、删除节点,那么如何做到节点的权限的控制呢?zookeeper的access control list 访问控制列表可以做到这一点。
  acl 权限控制,使用scheme:id:permission 来标识,主要涵盖 3 个方面:
    1)权限模式(scheme):授权的策略
    2)授权对象(id):授权的对象

    3)权限(permission):授予的权限

  zookeeper的acl权限控制的特性

    1)zooKeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限

    2)每个znode支持设置多种权限控制方案和多个权限

    3)子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点

 

8.2 权限模式

  采用何种方式授权

  world:对所有用户授权(默认的)
  ip:对指定ip用户授权
  auth:对某个指定用户授权(用户:密码  密码可以是明文的)
  digest:对某个指定用户授权(用户:密码  密码必须是加密的)

 

8.3 授权的对象

  授权模式使用world:授权对象只有一种:anyone -登录zookeeper的所有人

  授权模式使用ip:ip地址

  授权模式使用auth:指定的用户

  授权模式使用digest:指定的用户

 

8.4 授权的权限

  create、delete、read、writer、admin也就是 增、删、改、查、管理权限,这5种权限简写为cdrwa,注意:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限

8.5 授权相关命令

  getAcl 命令:获取某个节点的 acl 权限信息。

  setAcl 命令:设置某个节点的 acl 权限信息。

  addauth 命令:输入认证授权信息,注册时输入明文密码,加密形式保存

getAcl - 最开始默认是world:anyone

 

8.6 授权实例

1)world模式

  

  

  

 

2)ip模式

  设置ip权限

  

  远程登录zookeeper命令:./zkCli.sh -server ip

 

3)auth模式

  

  添加用户(这个操作将用户user1加入了当前会话,当前会话可以访问user1的节点)

  

  设置权限

  

  获取权限

  

  获取数据

  

  qiut退出当前会话后,重新登录,获取数据,权限不足

  

  再次添加用户

  

 

4)digest模式

  

  设置权限,需要加上密码,且密码是密文

  获取密文(账号user2 密码 user2)

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

  结果:ExK4ZEpM5XR9l8dLA7B6b79kLIo=

  设置权限(密码是密文)

  

  获取权限,权限不足

  

  添加用户(密码明文)

  

  获取权限

  

 

5)多种授权模式

  

  授权,多种授权用逗号隔开

  

  添加用户

  

  获取数据

  

 

8.7 超级管理员    

echo -n super:admin | openssl dgst -binary -sha1 | openssl base64
生成结果
 xQJmxLMiHGwaqBvst5y6rkB6HQs
 nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"  \
    -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' \

  这就是脚本中启动zookeeper的命令,默认只有以上两个配置项,我们需要加一个超管的配置项 

"-
Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBv
st5y6rkB6HQs="

  那么修改以后这条完整命令变成了

nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-
Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBv
st5y6rkB6HQs=" \
    -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' \

  重启zookeeper  ps-ef|grep zookeeper   kill - 9 xxx 杀掉进程  

  之后启动zookeeper

  创建节点/www

    create /www

  设置权限

    setAcl /www auth:user3:cdrwa

  获取数据,权限不足,添加超级管理员再获取