java zk客户端连接_Zookeeper基础,客户端使用,Java / Scala API调用

zookeeper基础

ZooKeeper 是一个分布式的应用程序协调服务。它提供了简单原始的功能,分布式应用可以基于它实现更高级 的服务, 比如分布式同步, 配置管理, 集群管理, 命名空间,队列管理。它使用文件系统目录树作为数据模型。

Zookeeper和 linux 的文件系统很像,也是树状,这样就可以确定每个路径都是唯一的,对于命名空间的操作必须都是绝对路径操作。与 linux 文件系统不同的是,linux 文件系统有目录和文件的区别,而 Zookeeper 统一叫做znode。

znode即是文件夹又是文件的概念,每个 znode 有唯一的路径标识,既能存储数据,也能创建子 znode,zookeeper和文件系统一样能够自由的增加、删除znode,唯一的不同在于znode是可以存储数据的。

znode 只适合存储非常小量的数据,不能超过 1M,最好小于 1K。

Znode节点类型

有四种类型的znode:

PERSISTENT-持久化目录节点:客户端与zookeeper断开连接后,该节点依旧存在

PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点:客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

EPHEMERAL-临时目录节点:客户端与zookeeper断开连接后,该节点被删除

EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点:客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

zookeeper客户端操作

(1).使用zookeeper-client连接zookeeper

不指定-server默认localhost:2181

zookeeper-client -server chd04:2181

(2). help命令

zookeeper-client help

ZooKeeper -server host:port cmd args

stat path [watch]

set path data [version]

ls path [watch]

delquota [-n|-b] path

ls2 path [watch]

setAcl path acl

setquota -n|-b val path

history

(3). get命令

get命令用于获取节点的数据,注意节点的路径必须是以/开头的路径。

get /kafka/config/topics/test_gp

[zk: localhost:2181(CONNECTED) 6] get /kafka/config/topics/test_gp

{"version":1,"config":{}}

cZxid = 0x35006dcb7f

ctime = Thu Jul 02 18:31:37 CST 2020

mZxid = 0x35006dcb7f

mtime = Thu Jul 02 18:31:37 CST 2020

pZxid = 0x35006dcb7f

cversion = 0

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 25

numChildren = 0

数据是{"version":1,"config":{}},其他参数说明

cZxid:节点创建时的zxid

ctime:节点创建时间

mZxid:节点最近一次更新时的zxid

mtime:节点最近一次更新的时间

cversion:子节点数据更新次数

dataVersion:本节点数据更新次数

aclVersion:节点ACL(授权信息)的更新次数

ephemeralOwner:如果该节点为临时节点,ephemeralOwner值表示与该节点绑定的session id. 如果该节点不是临时节点,ephemeralOwner值为0

dataLength:节点数据长度是25

numChildren:子节点个数是0

(4). stat命令

该参数的输出等同于的get的额外信息输出。

[zk: localhost:2181(CONNECTED) 7] stat /kafka/config/topics/test_gp

cZxid = 0x35006dcb7f

ctime = Thu Jul 02 18:31:37 CST 2020

mZxid = 0x35006dcb7f

mtime = Thu Jul 02 18:31:37 CST 2020

pZxid = 0x35006dcb7f

cversion = 0

(5). create命令

create创建节点

[zk: localhost:2181(CONNECTED) 10] create /test some-value

Created /test

子节点只能在父节点上依次创建,现在test下创建a存储null,再在a下创建value存储false

[zk: localhost:2181(CONNECTED) 107] create /test/a null

Created /test/a

[zk: localhost:2181(CONNECTED) 108] create /test/a/value false

Created /test/a/value

(6). set命令

set命令用于设置和修改节点的数据。

[zk: localhost:2181(CONNECTED) 16] set /test other-value

cZxid = 0x3b0011a50d

ctime = Wed Sep 09 17:17:30 CST 2020

mZxid = 0x3b0011a548

mtime = Wed Sep 09 17:19:49 CST 2020

pZxid = 0x3b0011a50d

cversion = 0

(7). ls命令

ls命令用于获取路径下的节点信息,路径为绝对路径。

[zk: localhost:2181(CONNECTED) 23] ls /kafka/config

[changes, clients, topics]

ls2命令

ls2命令比ls命令多输出本节点信息。

[zk: localhost:2181(CONNECTED) 24] ls2 /kafka/config

[changes, clients, topics]

cZxid = 0x20000014c

ctime = Thu Mar 14 14:40:56 CST 2019

mZxid = 0x20000014c

mtime = Thu Mar 14 14:40:56 CST 2019

(8). history命令

history用于列出最近的命令历史。

[zk: localhost:2181(CONNECTED) 25] history

15 - ls /test

16 - set /test other-value

17 - get /test

18 - ls

19 - ls /

20 - ls /kafka

(9). delete命令

delete命令用于删除节点。

[zk: localhost:2181(CONNECTED) 28] delete /test

如果该节点有子节点,则报错非空节点

[zk: localhost:2181(CONNECTED) 86] delete /test

Node not empty: /test

rmr命令

删除节点,有子节点一并删除

[zk: localhost:2181(CONNECTED) 90] rmr /test

(10). quit命令

退出客户端。

Java / Scala API使用案例

分别使用Java,Scala滴啊用zookeeper API创建ZK单例,实现读取和修改ZK节点数据。

Java

import org.apache.zookeeper.*;

import org.apache.zookeeper.common.PathUtils;

import org.apache.zookeeper.data.Stat;

import java.util.Arrays;

import java.util.List;

import java.util.Properties;

public class ZKUtils implements Watcher {

private static ZKUtils instance;

private static ZooKeeper zk;

private ZKUtils(Properties prop) {

try {

zk = new ZooKeeper(prop.getProperty("ZK_HOST"), 20000, this);

} catch (Exception e) {

e.printStackTrace();

}

}

public static ZKUtils getInstance(Properties prop) {

if (instance == null) {

synchronized (ZKUtils.class) {

if (instance == null) {

try {

instance = new ZKUtils(prop);

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

return instance;

}

public void process(WatchedEvent watchedEvent) {

}

public String getData(String path) throws KeeperException, InterruptedException {

PathUtils.validatePath(path);

Stat stat = zk.exists(path, false);

String res = null;

if (stat != null) {

res = new String(zk.getData(path, false, stat));

}

return res;

}

public void createPath(String path) throws KeeperException, InterruptedException {

// 验证路径有效性

PathUtils.validatePath(path);

List paths = Arrays.asList(path.split("/"));

for (int i = 2; i <= paths.size(); i ++) {

String tmpPath = "/" + String.join("/", paths.subList(1, i));

// 如果路径为空

if (zk.exists(tmpPath, false) == null) {

// 一层一层创建, value为空串.acl权限,节点类型

zk.create(tmpPath, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

}

}

}

public void setData(String path, String data) throws KeeperException, InterruptedException {

PathUtils.validatePath(path);

if (zk.exists(path, false) == null) {

this.createPath(path);

}

// -1是最新版本

zk.setData(path, data.getBytes(), -1);

}

public static void main(String[] args) throws KeeperException, InterruptedException {

Properties prop = new Properties();

prop.setProperty("ZK_HOST", "cloudera01,cloudera02,cloudera03");

// 读取zk数据

System.out.println(ZKUtils.getInstance(prop).getData("/test"));

// 创建路径,节点存储值空串

ZKUtils.getInstance(prop).createPath("/test/gp/b/c");

// 修改节点数据

ZKUtils.getInstance(prop).setData("/test/gp/b/c", "success");

}

}

scala

import org.apache.zookeeper._

import org.apache.zookeeper.common._

import java.util.Properties

import org.apache.zookeeper.data.Stat

class ZkUtilities() extends Watcher {

private var zk: ZooKeeper = _

private var pro: Properties = _

private def this(pro: Properties) = {

this()

this.pro = pro

zk = new ZooKeeper(pro.getProperty("ZK_HOST"), 20000, this)

}

@Override

def process(event: WatchedEvent) {

//no watching

}

private def createPath(path: String, zk: ZooKeeper): Unit = {

//创建路径

PathUtils.validatePath(path)

var parentPath = path.substring(0, path.indexOf("/", 0) + 1)

while (parentPath != null && !parentPath.isEmpty) {

if (zk.exists(parentPath, false) == null) {

// 同步创建,acl权限完全开放,节点类型持久化节点

zk.create(parentPath, "".getBytes, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

}

if (parentPath.equals(path)) {

parentPath = null

} else {

var idx = path.indexOf("/", parentPath.length() + 1)

if (-1 == idx) {

idx = path.length

}

parentPath = path.substring(0, idx)

}

}

}

def setData(path: String, data: String): Stat = {

if (zk.exists(path, false) == null) {

createPath(path, zk)

}

zk.setData(path, data.getBytes, -1)

}

def getData(path: String): String = {

val stat = zk.exists(path, false)

if (stat == null) {

null

} else {

new String(zk.getData(path, false, stat))

}

}

}

object ZkUtilities {

private var zkUtilities: ZkUtilities = _

def getIns(prop: Properties): ZkUtilities = {

this.synchronized {

if (zkUtilities == null) {

zkUtilities = new ZkUtilities(prop)

}

zkUtilities

}

}

def main(args: Array[String]): Unit = {

val prop = new Properties()

prop.setProperty("ZK_HOST", "cloudera01,cloudera02,cloudera03")

var res = ZkUtilities.getIns(prop).getData("/test/a/value")

println(res) // false

ZkUtilities.getIns(prop).setData("/test/a/value", "true")

res = ZkUtilities.getIns(prop).getData("/test/a/value")

println(res) // true

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值