ZooKeeper 集群使用(Cli and JavaAPI)
1、ZooKeeper 集群 cli 使用
1.1、连接 ZooKeeper 服务器
首先,我们在 zookeeper 安装路径下,可以用命令 bin/zkCli.sh 进入 ZooKeeper 的命令行客户端,如果配置了 zookeeper 环境变量的话,可以在其它路径下直接用命令 zkCli.sh 进入 ZooKeeper 的命令行客户端,这种是直接连接本机的 ZooKeeper 服务器。
还有一种方式,可以连接其他的 ZooKeeper 服务器,只需要我们在命令后面接一个参数 -server 就可以了。例如:
zkCli.sh -server hadoop01:2181
进入命令行之后,键入 help 可以查看简易的命令帮助文档,如下图:
1.2、ZooKeeper cli 常用命令
zookeeper cli 命令 | 释义 |
---|---|
ls / | 查看 znode 根节点下的子节点 |
ls /zookeeper | 查看 znode 子节点 zookeeper 下的子节点 |
create /zktest “myData” | 创建 znode 节点 zktest,并给与该节点数据信息 “myData” |
get /zktest | 获取节点 zktest 数据信息 |
set /zktest “myData2” | 设置节点 zktest 数据信息(更新) |
ls /zktest watch | 监听 znode 事件,就对 zktest 节点的子节点变化事件注册了监听 |
get /zktest watch | 监听 znode 事件,就对 zktest 节点的数据内容变化事件注册了监听 |
create -e /zktest/temporary “myTemporaryNode” | 创建临时 znode 节点 |
create -s /zktest/order “myOrderNode” | 创建顺序 znode 节点 |
delete /zktest/temporary | 删除 znode 节点,只能删除没有子 znode 的 znode |
rmr /zktest | 删除 znode 节点,不管里头有多少 znode,统统删除 |
1.3、znode 数据信息字段
获取 znode 数据信息:
get /zktest
znode 数据信息字段 | 释义 |
---|---|
myData2 | 节点数据 |
cZxid = 0x2a0000002 | 节点创建的时候的 zxid。The zxid of the change that caused this znode to be created. |
ctime = Wed Mar 03 10:03:15 CST 2021 | 节点创建的时间。The time in milliseconds from epoch when this znode was created. |
mZxid = 0x2a00000003 | 节点修改的时候的 zxid,与子节点的修改无关。The zxid of the change that last modified this znode. |
mtime = Wed Mar 03 10:08:11 CST 2021 | 节点的修改的时间。The time in milliseconds from epoch when this znode was last modified. |
pZxid = 0x2a00000002 | 和子节点的创建/删除对应的 zxid,和修改无关,和孙子节点无关。The zxid of the change that last modified children of this znode. |
cversion = 0 | 子节点的更新次数。The number of changes to the children of this znode. |
dataVersion = 1 | 节点数据的更新次数。The number of changes to the data of this znode. |
aclVersion = 0 | 节点(ACL)的更新次数。The number of changes to the ACL of this znode. |
ephemeralOwner = 0x0 | 如果该节点为 ephemeral 节点, ephemeralOwner 值表示与该节点绑定的 session id. 如果该节点不是 ephemeral 节点, ephemeralOwner 值为 0。The session id of the owner of this znode if the znode is an ephemeral node. If it is not an ephemeral node, it will be zero. |
dataLength = 7 | 节点数据的字节数。The length of the data field of this znode. |
numChildren = 0 | 子节点个数,不包含孙子节点。The number of children of this znode. |
2、ZooKeeper 四字命令
使用格式:
[root@hadoop02 ~]#
echo conf|nc hadoop02 2181
注意:需要安装 nc,不然不能使用
yum install -y nc
四字命令 | 释义 |
---|---|
conf | 输出相关服务配置的详细信息。 |
cons | 列出所有连接到服务器的客户端的完全的连接/会话的详细信息。包括 “接受/发送” 的包数量、会话 id、操作延迟、最后的操作执行等等信息。 |
dump | 列出未经处理的会话和临时节点。 |
envi | 输出关于服务环境的详细信息(区别于 conf 命令)。 |
reqs | 列出未经处理的请求。 |
ruok | 测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应。 |
stat | 输出关于性能和连接的客户端的列表。 |
wchs | 列出服务器 watch 的详细信息。 |
wchc | 通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。 |
wchp | 通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。 |
3、ZooKeeper 集群 Java API 使用
3.1、常用 API 方法
常用API 方法 | 释义 |
---|---|
create(path, data, flags) | 创建一个 znode, path 是其路径,data 是存储在该 ZNode 上的数据,flags 常用的有: PERSISTEN, PERSISTENT_SEQUENTAIL, EPHEMERAL, EPHEMERAL_SEQUENTAIL。 |
delete(path, version) | 删除一个 ZNode,可以通过 version 删除指定的版本, 如果 version 是 -1的话,表示删除所有的版本。 |
exists(path, watch) | 判断指定 ZNode 是否存在,并设置是否 Watch 这个 ZNode。这里如果要设置 Watcher 的话,Watcher 是在创建 ZooKeeper 实例时指定的,如果要设置特定的 Watcher 的话,可以调用另一个重载版本的 exists(path, watcher)。以下几个带 watch 参数的 API 也都类似。 |
getData(path, watch) | 读取指定 ZNode 上的数据,并设置是否 watch 这个 ZNode。 |
setData(path, watch) | 更新指定 ZNode 的数据,并设置是否 Watch 这个 ZNode。 |
getChildren(path, watch) | 获取指定 ZNode 的所有子 ZNode 的名字,并设置是否 Watch 这个 ZNode。 |
sync(path) | 把所有在 sync 之前的更新操作都进行同步,达到每个请求都在半数以上的 ZooKeeper Server 上生效。path 参数目前没有用。 |
setAcl(path, acl) | 设置指定 ZNode 的 Acl 信息。 |
getAcl(path) | 获取指定 ZNode 的 Acl 信息。 |
3.2、代码实现基本操作
package com.zc.bigdata;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
/**
* @作者: zc
* @时间: 2021/3/3 11:54
* @描述: zookeeper 基本测试
* 获取 zookeeper 链接
* 判断节点是否存在
* 创建节点
* 获取节点数据信息
* 修改节点数据信息
* 获取节点权限
* 获取路径下的子节点
* 删除节点
* 关闭 zookeeper 链接
*/
public class ZooKeeperDemo {
// 客户端去请求链接的时候的服务器链接地址信息
private static String connectString = "hadoop01:2181,hadoop02:2181,hadoop03:2181,hadoop04:2181";
// 客户端去请求链接的超时时长
private static int sessionTimeout = 4000;
// 节点名称,统一命名
private static String znode = "/zktest/apinode";
// 链接对象
private static ZooKeeper zk = null;
/**
* 获取 Zookeeper 链接
* @throws Exception 链接异常
*/
public static void init() throws Exception {
zk = new ZooKeeper(connectString, sessionTimeout, null);
}
/**
* 判断节点是否存在
* @param znode 节点
* @return 返回存在 true,反之 false
* @throws Exception 判断异常
*/
public static Boolean existsFlag(String znode) throws Exception {
Stat existsflag = zk.exists(znode, null);
if (existsflag != null) return true;
return false;
}
/**
* 创建 znode
* @param znode 创建的节点
* @param nodedata 创建的节点的数据
* @return 返回结果
* @throws Exception 创建异常
*/
public static String createNode(String znode, String nodedata)
throws Exception {
if (zk == null){
return "ZooKeeper 没有链接!!!";
}
if (existsFlag(znode)){
return znode + " 节点已经存在,节点创建失败";
}
return zk.create(znode, nodedata.getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT) + "节点创建成功";
}
/**
* 获取节点数据
* @param znode 待获取数据的节点
* @return 返回节点数据信息
* @throws Exception 获取异常
*/
public static String getNodeData(String znode) throws Exception {
if (zk == null){
return "ZooKeeper 没有链接!!!";
}
if (!existsFlag(znode)){
return znode + " 节点不存在,获取节点数据失败";
}
return znode + " 节点数据信息:" + new String(zk.getData(znode, null, null));
}
/**
* 修改节点数据,获取节点数据修改时间
* @param znode 待修改数据的节点
* @param newNodeData 新数据
* @return 返回修改时间
* @throws Exception 修改数据异常
*/
public static String setNodeData(String znode, String newNodeData) throws Exception {
if (zk == null){
return "ZooKeeper 没有链接!!!";
}
if (!existsFlag(znode)){
return znode + " 节点不存在,修改节点数据失败";
}
// 修改节点数据
Stat setData = zk.setData(znode, newNodeData.getBytes(), -1);
// 获取节点数据修改时间
return znode + " 节点数据已经修改,修改时间:" +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(setData.getMtime()));
}
/**
* 获取节点的权限信息
* @param znode 节点
* @throws Exception 查看异常
*/
public static void getNodeACL(String znode) throws Exception {
if (zk == null){
System.out.println("ZooKeeper 没有链接!!!");
return;
}
if (!existsFlag(znode)){
System.out.println(znode + " 节点不存在,查看节点权限失败");
return;
}
List<ACL> aclList = zk.getACL(znode, null);
for (ACL acl : aclList) {
System.out.println(acl.getPerms());
}
}
/**
* 获取路径下子节点
* @param path 路径
* @throws Exception 获取子节点异常
*/
public static void getChildrenNode(String path) throws Exception {
if (zk == null){
System.out.println("ZooKeeper 没有链接!!!");
return;
}
if (!path.equals("/") && !existsFlag(path)){
System.out.println(path + " 路径不存在,获取子节点失败");
return;
}
// 获取子节点
List<String> children = zk.getChildren(path, null);
if (children.isEmpty()){
System.out.println(path + " 该路径下没有子节点");
return;
}
for (String child : children) {
System.out.println(child);
}
}
/**
* 删除节点
* @param znode 待删除的节点
* @param version 删除节点信息版本
* @throws Exception 删除异常
*/
public static void deleteNode(String znode, int version) throws Exception {
if (zk == null){
System.out.println("ZooKeeper 没有链接!!!");
return;
}
if (!existsFlag(znode)){
System.out.println(znode + " 节点不存在,无法进行删除");
return;
}
// 删除节点
zk.delete(znode, version);
if (!existsFlag(znode)){
System.out.println(znode + " 节点不存在,已经删除成功");
}
}
public static void closeZK() throws Exception {
if (zk != null){
zk.close();
}
}
public static void main(String[] args) throws Exception {
// 获取 ZooKeeper 链接
// init();
// 创建 znode
System.out.println(createNode(znode, "test data"));
// 获取节点数据
// System.out.println(getNodeData(znode));
// 修改节点数据,获取节点数据修改时间
// System.out.println(setNodeData(znode, "new test data"));
// 获取修改后节点的数据
// System.out.println(getNodeData(znode));
// 获取 znode 的权限信息
// getNodeACL(znode);
// 判断节点是否存在
// Boolean existsFlag = existsFlag(znode);
// System.out.println(existsFlag ? znode + " 节点存在" : znode + " 节点不存在");
// 获取子节点
// getChildrenNode("/zktest");
// getChildrenNode(znode);
// 删除节点
// deleteNode("/zktest/apinode", -1);
// 关闭 zk 链接
closeZK();
}
}
4、学习内容
上节学习内容:ZooKeeper 集群搭建
下节学习内容:Zookeeper 选取机制与工作流程原理解析