1 常用命令
1.1 服务端常用命令
在准备好相应的配置之后,可以直接通过zkServer.sh 这个脚本进行服务的相关操作
- 启动ZK服务: sh bin/zkServer.sh start
- 查看ZK服务状态: sh bin/zkServer.sh status
- 停止ZK服务: sh bin/zkServer.sh stop
- 重启ZK服务: sh bin/zkServer.sh restart
1.2 客户端常用命令
使用 zkCli.sh -server 127.0.0.1:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。 命令行工具的一些简单操作如下:
- 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
- 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据
- 创建文件,并设置初始内容: create /zk "test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串
- 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串
- 修改文件内容: set /zk "zkbak" 对 zk 所关联的字符串进行设置
- 删除文件: delete /zk 将刚才创建的 znode 删除,如果存在子节点删除失败
- 递归删除:rmr /zk将刚才创建的 znode 删除,子节点同时删除
- 退出客户端: quit
- 帮助命令: help
1.3 ACL命令常用命令
getAcl
获取指定节点的ACL信息
create /testDir/testAcl deer # 创建一个子节点
getAcl /testDir/testAcl # 获取该节点的acl权限信息
setAcl
设置指定节点的ACL信息
setAcl /testDir/testAcl world:anyone:crwa # 设置该节点的acl权限
getAcl /testDir/testAcl # 获取该节点的acl权限信息,成功后,该节点就少了d权限
create /testDir/testAcl/xyz xyz-data # 创建子节点
delete /testDir/testAcl/xyz # 由于没有d权限,所以提示无法删除
addauth
注册会话授权信息
- 1 Auth
addauth digest user1:123456 # 需要先添加一个用户
setAcl /testDir/testAcl auth:user1:123456:crwa # 然后才可以拿着这个用户去设置权限
getAcl /testDir/testAcl # 密码是以密文的形式存储的
create /testDir/testAcl/testa aaa
delete /testDir/testAcl/testa # 由于没有d权限,所以提示无法删除
退出客户端后:
ls /testDir/testAcl #没有权限无法访问
create /testDir/testAcl/testb bbb #没有权限无法访问
addauth digest user1:123456 # 重新新增权限后可以访问了
- 2 Digest
auth与digest的区别就是,前者使用明文密码进行登录,后者使用密文密码进行登录
create /testDir/testDigest data
addauth digest user1:123456
setAcl /testDir/testDigest digest:user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s=:crwa # 使用digest来设置权限
注意:这里如果使用明文,会导致该znode不可访问
通过明文获得密文
shell>
java -Djava.ext.dirs=/soft/zookeeper-3.4.12/lib -cp /soft/zookeeper-3.4.12/zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider deer:123456
deer:123456->deer:ACFm5rWnnKn9K9RN/Oc8qEYGYDs=
- 3 acl命令行ip
create /testDir/testIp data
setAcl /testDir/testIp ip:192.168.30.10:cdrwa
getAcl /testDir/testIp
1.4 常用四字命令
ZooKeeper 支持某些特定的四字命令字母与其的交互。用来获取 ZooKeeper 服务的当前状态及相关信息。可通过 telnet 或 nc 向 ZooKeeper 提交相应的命令 :
当然,前提是安装好了nc
echo stat|nc 127.0.0.1 2181 来查看哪个节点被选择作为follower或者leader
使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。
echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。
echo kill | nc 127.0.0.1 2181 ,关掉server
echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。
echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息
echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。
echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。
echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。
echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。
1.5 ZooKeeper 日志可视化
前面以及讲了两个非常重要的配置一个是dataDir,存放的快照数据,一个是dataLogDir,存放的是事务日志文件
java -cp /soft/zookeeper-3.4.12/zookeeper-3.4.12.jar:/soft/zookeeper-3.4.12/lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.LogFormatter log.1
1.6 ZooKeeper 快照可视化
java -cp /soft/zookeeper-3.4.12/zookeeper-3.4.12.jar:/soft/zookeeper-3.4.12/lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.SnapshotFormatter log.1
2 zk原生API
2.1 zookeeper官方提供的java客户端API;
-
创建会话
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,
long sessionId, byte[] sessionPasswd, boolean canBeReadOnly) -
创建节点
public String / void create(final String path, byte data[], List<ACL> acl,
CreateMode createMode, StringCallback cb, Object ctx) -
读取数据
public List<String> / void getChildren(final String path, Watcher watcher,
Stat stat, Children2Callback cb, Object ctx)
public List<String> / void getData(final String path, Watcher watcher,
Stat stat, DataCallback cb, Object ctx) -
更新数据
public Stat / void setData(final String path, byte data[], int version,
StatCallback cb, Object ctx) -
检测节点是否存在
public Stat / void exists(final String path, Watcher watcher,
StatCallback cb, Object ctx) -
权限控制
public void addAuthInfo(String scheme, byte auth[])
watch
org.apache.zookeeper.Watcher(KeeperState、EventType)
(1)没有专门的API去注册watcher,依附于增删改查API;
(2) watch是一次性产品
(3) watch的process方法中,可对不同事件进行处理;
2.2 Zookeeper原生客户端在开发支持上的弊端
- 会话的连接是异步的;
- Watch需要重复注册 ;
- Session重连机制;
- 开发复杂性较高;
3 ZkClient
开源的zk客户端,在原生API基础上封装,是一个更易于使用的zookeeper客户端;
3.1 ZkClient的maven依赖
<!-- zkclient依赖 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
3.2 ZkClient的API
-
创建会话(同步,重试)
public ZkClient(final String zkServers, final int sessionTimeout,
final int connectionTimeout, final ZkSerializer zkSerializer,
final long operationRetryTimeout) -
创建节点(同步,递归创建)
public String create(String path,Object data,final List<ACL> acl,CreateMode mode)
public void createPersistent(String path,boolean createParents,List<ACL> acl)
public void createPersistent(String path, Object data, List<ACL> acl)
public String createPersistentSequential(String path,Object data,List<ACL> acl)
public void createEphemeral(String path, Object data, List<ACL> acl)
public String createEphemeralSequential(String path,Object data,List<ACL> acl) -
删除节点(同步,递归删除)
public boolean delete(String path,int version)
public boolean deleteRecursive(String path) -
获取节点(同步,避免不存在异常)
public List<String> getChildren(String path)
public <T> T readData(String path, boolean returnNullIfPathNotExists)
public <T> T readData(String path, Stat stat) - **更新节点(同步,实现CAS,状态返回)
public void writeData(String path, Object datat, int expectedVersion)
public Stat writeDataReturnStat(String path,Object datat,int expectedVersion) -
检测节点存在(同步)
public boolean exists(String path) -
权限控制(同步)
public void addAuthInfo(String scheme, final byte[] auth);
public void setAcl(final String path, final List<ACL> acl); - 监听器
序号 | 监听器 | 注册API |
---|---|---|
1 | IZkStateListener | (un)subscribeStateChanges(IZkStateListener listener) |
2 | IZkDataListener | subscribeDataChanges(IZkStateListener listener) |
3 | IZkDataListener | (un)subscribeChildChanges(IZkStateListener listener) |
4 Curator
开源的zk客户端,在原生API基础上封装,apache顶级项目;
4.1 Curator的maven依赖
Curator采用Fluent风格API
<!-- curator依赖 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
对序列化支持不太好 http://blog.itpub.net/29254281/viewspace-2097459/
4.2 Curator的API
创建会话(同步,重试)
CuratorFrameworkFactory.newClient(String connectString, int sessionTimeoutMs,
int connectionTimeoutMs, RetryPolicy retryPolicy)
CuratorFrameworkFactory.builder().connectString("192.168.11.56:2180")
.sessionTimeoutMs(30000).connectionTimeoutMs(30000)
.canBeReadOnly(false)
.retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE))
.build();
retryPolicy 连接策略:
RetryOneTime: 只重连一次.
RetryNTime: 指定重连的次数N.
RetryUtilElapsed: 指定最大重连超时时间和重连时间间隔,间歇性重连直到超时或者链接成功.
ExponentialBackoffRetry: 基于"backoff"方式重连,和RetryUtilElapsed的区别是重连的时间间隔是动态的.
BoundedExponentialBackoffRetry: 同ExponentialBackoffRetry,增加了最大重试次数的控制.创建节点
client.create().creatingParentIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(aclList)
.forPath(path, "hello, zk".getBytes());删除节点
client.delete().guaranteed().deletingChildrenIfNeeded()
.withVersion(version).forPath(path)获取节点
client.getData().storingStatIn(stat).forPath(path);
client.getChildren().forPath(path);更新节点
client.setData().withVersion(version).forPath(path, data)判断节点是否存在
client.checkExists().forPath(path);设置权限
Build.authorization(String scheme, byte[] auth)
client.setACL().withVersion(version)
.withACL(ZooDefs.Ids.CREATOR_ALL_ACL)
.forPath(path);监听器(避免反复监听)
Cache是curator中对事件监听的包装,对事件的监听可以近似看做是本地缓存视图和远程zk视图的对比过程
NodeCache 节点缓存用于处理节点本身的变化 ,回调接口NodeCacheListener
PathChildrenCache 子节点缓存用于处理节点的子节点变化,回调接口PathChildrenCacheListener
TreeCache NodeCache和PathChildrenCache的结合体,回调接口TreeCacheListener事务支持(保证一组操作的原子性)
Collection<CuratorTransactionResult> results = client.transaction().forOperations(operations);异步支持
引入BackgroundCallback接口,用于处理异步接口调用之后服务端返回的结果信息
public void processResult(CuratorFramework client, CuratorEvent event)
CuratorEventType 事件类型
org.apache.zookeeper.KeeperException.Code 服务器响应码(标识结果)