本片介绍两方面内容,一方面是命令行操作,另一方面是Java调用API。

ZooKeeper集群环境的搭建在Hadoop集群搭建里已经讲过了,这里不再赘述,本篇内容基于zk3.5.8。

这里补充一点,除了前面提到的leader和follower之外,zk还有一种角色叫observer。可以这么理解,follower是候选人,leader是当前的领导者,observer是普通人。leader只能从follower中选出,observer不参与选举但可以提供读服务。

observer的配置,只需要在zoo.cfg中增加server.1=server01:2888:3888:observer就行,可以在不影响写性能的前提下扩展读并发。

命令行操作

首先启动zk集群,进入命令行。

[hadoop@server01 ~]$ zkServer.sh start
/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/apache-zookeeper-3.5.8/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[hadoop@server01 ~]$ zkServer.sh status
/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/apache-zookeeper-3.5.8/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
[hadoop@server01 ~]$ zkCli.sh

官网说From the shell, type help to get a listing of commands that can be executed from the client,我试着输入help命令,命令列表确实输出了,但是注意看最后一行。

[zk: server01:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path
delquota [-n|-b] path
get [-s] [-w] path
getAcl [-s] path
history
listquota path
ls [-s] [-w] [-R] path
ls2 path [watch]
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
rmr path
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b val path
stat [-w] path
sync path
Command not found: Command not found help

最后一行提示根本就没有help这个命令。官网这不是误导人嘛。

先试试ls命令,我这个zk已经有hadoop和yarn两个集群用来选主了,所有有它们的目录。

[zk: server01:2181(CONNECTED) 1] ls /
[hadoop-ha, yarn-leader-election, zookeeper]

创建一个目录,并给它赋值。再把值取出来。

[zk: server01:2181(CONNECTED) 2] create /game "this is a game directory"
Created /game
[zk: server01:2181(CONNECTED) 3] get /game
this is a game directory
[zk: server01:2181(CONNECTED) 4] ls /
[game, hadoop-ha, yarn-leader-election, zookeeper]

现在有没有感性认识了?这个目录树的非叶子可以存储数据,是一个键值对。

[zk: server01:2181(CONNECTED) 7] create /game/pal "XianJianXiLie"
Created /game/pal
[zk: server01:2181(CONNECTED) 8] get /game/pal
XianJianXiLie
[zk: server01:2181(CONNECTED) 9] stat /game/pal
cZxid = 0xd0000000a
ctime = Wed Mar 10 22:16:50 CST 2021
mZxid = 0xd0000000a
mtime = Wed Mar 10 22:16:50 CST 2021
pZxid = 0xd0000000a
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13
numChildren = 0

把/game/pal的值修改成李逍遥,注意观察,mZxid和dataVersion 加1了,数据长度变了,其他属性没变化。

[zk: server01:2181(CONNECTED) 10] set /game/pal "LiXiaoYao"
[zk: server01:2181(CONNECTED) 11] stat /game/pal
cZxid = 0xd0000000a
ctime = Wed Mar 10 22:16:50 CST 2021
mZxid = 0xd0000000b
mtime = Wed Mar 10 22:18:08 CST 2021
pZxid = 0xd0000000a
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 0
[zk: server01:2181(CONNECTED) 12] stat /game
cZxid = 0xd00000009
ctime = Wed Mar 10 22:09:04 CST 2021
mZxid = 0xd00000009
mtime = Wed Mar 10 22:09:04 CST 2021
pZxid = 0xd0000000a
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 24
numChildren = 1

现在把znode删掉,它提示不能删除非空目录。我们还有个deleteall命令,这个可以级联删除。

[zk: server01:2181(CONNECTED) 13] delete /game
Node not empty: /game
[zk: server01:2181(CONNECTED) 14] deleteall /game
[zk: server01:2181(CONNECTED) 15] ls /
[hadoop-ha, yarn-leader-election, zookeeper]

上面创建的是永久节点。还可以用-e参数创建临时节点,当客户端断开连接后,节点自动消失。用-s创建序列节点,zk自动在节点名后面补十位递增数字。

[zk: server01:2181(CONNECTED) 4] create -e /game/3DO
Created /game/3DO
[zk: server01:2181(CONNECTED) 5] ls /game
[3DO]
[zk: server01:2181(CONNECTED) 6] create -s /game/3DO
Created /game/3DO0000000001
[zk: server01:2181(CONNECTED) 7] ls /game
[3DO, 3DO0000000001]

上面的命令在server01的客户端上创建了一个临时节点/game/3DO和一个序列节点/game/3DO0000000001,从server02上再连一个客户端看看。

[zk: server02:2181(CONNECTED) 0] ls /game
[3DO, 3DO0000000001]

server02上这两个目录也存在。现在把server01客户端断开连接。

[zk: server01:2181(CONNECTED) 8] quit

WATCHER::

WatchedEvent state:Closed type:None path:null
2021-03-11 10:39:09,535 [myid:] - INFO [main:ZooKeeper@1422] - Session: 0x10000138b4a0001 closed
2021-03-11 10:39:09,537 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@524] - EventThread shut down for session: 0x10000138b4a0001

从server02上再看看这个目录下有什么。

[zk: server02:2181(CONNECTED) 1] ls /game
[3DO0000000001]

可以看到临时节点/game/3DO消失了。

JAVA API

在pom.xml文件里增加配置

      <dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.8</version>
</dependency>

创建节点

先试试创建持久化节点。所有代码如下。

import org.apache.zookeeper.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import java.io.IOException;
import java.util.concurrent.CountDownLatch; public class ZooKeeperTest { ZooKeeper client = null; @Before
public void init() throws InterruptedException, IOException {
String url = "server01:2181,server02:2181,server03:2181";
CountDownLatch latch = new CountDownLatch(1);
client = new ZooKeeper(url, 5000, (event) -> {if(event.getState() == Watcher.Event.KeeperState.SyncConnected) latch.countDown();});
latch.await();
} @Test
public void createZnode() throws KeeperException, InterruptedException {
//持久化节点
String znode1 = client.create("/game/ThreeKingdom","The story of many heros".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} @After
public void destroy() throws InterruptedException {
if(client != null)
client.close();
}
}

在初始化方法里,创建了zk的客户端,但是这个客户端并不是new ZooKeeper( )返回之后就立马可用,必须等到连接创建完毕后才能用。所以用到了Java的CountDownLatch,在watch事件状态为连接成功之后主线程才被唤醒。

执行createZnode( )方法之后,控制台输出如下

Process finished with exit code 0

通过命令行看看目录创建成功没有

[zk: server02:2181(CONNECTED) 4] ls /game
[3DO0000000001, ThreeKingdom]
[zk: server02:2181(CONNECTED) 5] get -s /game/ThreeKingdom
The story of many heros
cZxid = 0x250000000d
ctime = Thu Mar 11 11:51:04 CST 2021
mZxid = 0x250000000d
mtime = Thu Mar 11 11:51:04 CST 2021
pZxid = 0x250000000d
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 23
numChildren = 0

删除节点

    @Test
public void deleteZnode() throws KeeperException, InterruptedException {
//删除节点,这里的version参数必须与zk服务器最新的版本号一直,否则会抛异常BadVersionException。
//版本号是为了控制分布式更新的并发问题。如果不关心版本号,可以设置为-1
client.delete("/game/ThreeKingdom", -1); }

删除之后再通过命令行看看,/game下已经没有三国的目录了。

[zk: server02:2181(CONNECTED) 8] ls /game
[3DO0000000001]

修改节点信息

    @Test
public void setZnode() throws KeeperException, InterruptedException {
//
final Stat stat = client.setData("/game", "childhood memory".getBytes(), -1);
System.out.println(stat.toString());
}

控制台输出结果:

158913789957,158913789974,1615430142891,1615444561053,1,5,0,0,16,1,158913789971

Process finished with exit code 0

来看看setData返回的Stat包含哪些字段信息

public String toString() {
try {
ByteArrayOutputStream s = new ByteArrayOutputStream();
CsvOutputArchive a_ = new CsvOutputArchive(s);
a_.startRecord(this, "");
a_.writeLong(this.czxid, "czxid");
a_.writeLong(this.mzxid, "mzxid");
a_.writeLong(this.ctime, "ctime");
a_.writeLong(this.mtime, "mtime");
a_.writeInt(this.version, "version");
a_.writeInt(this.cversion, "cversion");
a_.writeInt(this.aversion, "aversion");
a_.writeLong(this.ephemeralOwner, "ephemeralOwner");
a_.writeInt(this.dataLength, "dataLength");
a_.writeInt(this.numChildren, "numChildren");
a_.writeLong(this.pzxid, "pzxid");
a_.endRecord(this, "");
return new String(s.toByteArray(), "UTF-8");
} catch (Throwable var3) {
var3.printStackTrace();
return "ERROR";
}
}

通过命令行获取/game的状态信息,与IDE控制台返回的一致

[zk: server02:2181(CONNECTED) 10] get -s /game
childhood memory
cZxid = 0x2500000005
ctime = Thu Mar 11 10:35:42 CST 2021
mZxid = 0x2500000016
mtime = Thu Mar 11 14:36:01 CST 2021
pZxid = 0x2500000013
cversion = 5
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 16
numChildren = 1

获取节点信息

    @Test
public void getZnode() throws KeeperException, InterruptedException {
//
final byte[] data = client.getData("/game", false, new Stat());
System.out.println(new String(data));
}

控制台输出结果

childhood memory

Process finished with exit code 0

注册监听

演示一下对一个已经存在的节点注册监听。先定义一个监听类,监听节点改变事件。

public class ZnodeChangeWatcher implements Watcher {
@Override
public void process(WatchedEvent watchedEvent) {
if(Event.EventType.NodeDataChanged == watchedEvent.getType()){
System.out.println("znode:"+watchedEvent.getPath()+"发生变化");
}
}
}

再添加一个测试方法,监听/game/ThreeKingdom节点。

    @Test
public void watchZnode() throws KeeperException, InterruptedException {
//
Watcher watcher = new ZnodeChangeWatcher();
client.exists("/game/ThreeKingdom",watcher);
Thread.sleep(Integer.MAX_VALUE);
}

通过命令行修改这个节点的值,先看看原值是The story of many heros,修改为The Story of three heros。

[zk: localhost:2181(CONNECTED) 1] get -s /game/ThreeKingdom
The story of many heros
cZxid = 0xf00000005
ctime = Sat Mar 13 22:43:41 CST 2021
mZxid = 0xf00000005
mtime = Sat Mar 13 22:43:41 CST 2021
pZxid = 0xf00000005
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 23
numChildren = 0
[zk: localhost:2181(CONNECTED) 2] set /game/ThreeKingdom "The Story of three heros"

切换到IDE控制台,看看输出结果。

znode:/game/ThreeKingdom发生变化

大数据学习(23)—— ZooKeeper实战的更多相关文章

  1. 大数据学习day20-----spark03-----RDD编程实战案例(1 计算订单分类成交金额,2 将订单信息关联分类信息,并将这些数据存入Hbase中,3 使用Spark读取日志文件,根据Ip地址,查询地址对应的位置信息

    1 RDD编程实战案例一 数据样例 字段说明: 其中cid中1代表手机,2代表家具,3代表服装 1.1 计算订单分类成交金额 需求:在给定的订单数据,根据订单的分类ID进行聚合,然后管理订单分类名称, ...

  2. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解

    引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...

  3. 大数据学习笔记——Hadoop编程实战之HDFS

    HDFS基本API的应用(包含IDEA的基本设置) 在上一篇博客中,本人详细地整理了如何从0搭建一个HA模式下的分布式Hadoop平台,那么,在上一篇的基础上,我们终于可以进行编程实操了,同样,在编程 ...

  4. 大数据学习:storm流式计算

    Storm是一个分布式的.高容错的实时计算系统.Storm适用的场景: 1.Storm可以用来用来处理源源不断的消息,并将处理之后的结果保存到持久化介质中. 2.由于Storm的处理组件都是分布式的, ...

  5. 大数据学习(16)—— HBase环境搭建和基本操作

    部署规划 HBase全称叫Hadoop Database,它的数据存储在HDFS上.我们的实验环境依然基于上个主题Hive的配置,参考大数据学习(11)-- Hive元数据服务模式搭建. 在此基础上, ...

  6. 大数据学习系列之五 ----- Hive整合HBase图文详解

    引言 在上一篇 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机) 和之前的大数据学习系列之二 ----- HBase环境搭建(单机) 中成功搭建了Hive和HBase的环 ...

  7. 大数据学习系列之六 ----- Hadoop+Spark环境搭建

    引言 在上一篇中 大数据学习系列之五 ----- Hive整合HBase图文详解 : http://www.panchengming.com/2017/12/18/pancm62/ 中使用Hive整合 ...

  8. 大数据学习系列之九---- Hive整合Spark和HBase以及相关测试

    前言 在之前的大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 中介绍了集群的环境搭建,但是在使用hive进行数据查询的时候会非常的慢,因为h ...

  9. 大数据学习系列之—HBASE

    hadoop生态系统 zookeeper负责协调 hbase必须依赖zookeeper flume 日志工具 sqoop 负责 hdfs dbms 数据转换 数据到关系型数据库转换 大数据学习群119 ...

  10. 大数据学习之Hadoop快速入门

    1.Hadoop生态概况 Hadoop是一个由Apache基金会所开发的分布式系统集成架构,用户可以在不了解分布式底层细节情况下,开发分布式程序,充分利用集群的威力来进行高速运算与存储,具有可靠.高效 ...

随机推荐

  1. Centos8.3、docker部署springboot项目实战记录

    引言    目前k8s很是火热,我也特意买了本书去学习了一下,但是k8s动辄都是成百上千的服务器运维,对只有几台服务器的应用来说使用k8s就有点像大炮打蚊子.只有几台服务器的应用运维使用传统的tomc ...

  2. Linux安装及管理程序

    一,常见的软件包封装类型 二.RPM包管理工具 三.查询RPM软件包信息 四.安装.升级.卸载RPM软件包 五.解决软件包依赖关系的方法 六.源代码编译 七.安装yum源仓库 一,常见的软件包封装类型 ...

  3. 简述MSTP与配置

    一.简介 二.MSTP概述 三.功能 四.配置命令 一.简介 多生成树协议MSTP(Multiple Spanning Tree Protocol)是IEEE 802.1s中定义的生成树协议,通过生成 ...

  4. NAT介绍与配置

    一,NAT定义 二.NAT的分类 三,NAT配置实验 一,NAT定义 NAT(Network Address Translation),网络地址转换技术,随着Internet的发展,IPv4地址枯竭已 ...

  5. 企业该选择什么样的CRM系统

    不论您是需要CRM系统来优化业务流程,还是准备更换一款新的CRM系统,在这之前都应该先明确企业的需求,并了解CRM的哪些功能能够对企业有所帮助.例如,企业的管理者想了解每个销售人员的业绩情况,那么就应 ...

  6. 整理!企业选择好用的CRM系统的要点(上)

    随着市场经济的发展,对任何行业的企业来说,客户都是非常重要的一个部分.CRM系统帮助企业做到以客户为中心,它可以根据客户的具体要求进行跟进和反馈,在很大程度上提高公司的客户服务水平和客户满意度,进而提 ...

  7. css文字动画(自动换文字)

    html: <div class="content"> <div class="content__container"> <p c ...

  8. Docker:docker搭建redis6.0.8集群

    下载redis镜像 #拉取镜像 docker pull redis:6.0.8 查看版本 #查看版本 docker inspect redis 生成redis.conf配置文件 #在 /home/re ...

  9. Linux:从windows到linux的shell脚本编码和格式

    从windows到linux的shell脚本编码和格式问题 异常问题 :set ff=unix 启动脚本在启动时报错比如执行sh start.sh,时会报Command not found等等的错误, ...

  10. php mkdir 创建多级目录以及修改权限

    mkdir() 用法:mkdir($path,0777,true); 第一个参数:必须,代表要创建的多级目录的路径:第二个参数:设定目录的权限,默认是 0777,意味着最大可能的访问权:注意:mode ...