一、单机模式
- 解压文件(我这里安装到home目录下的software):
#tar -zxvf zookeeper-3.4.7.tar.gz - 进入zookeeper目录,进入conf目录:# cd zookeeper-3.4.7/conf
- 复制:
# cp zoo_sample.cfg zoo.cfg
- 对于单机版来说,无需配置,直接进入bin目录:# cd bin,启动zookeerper
。# sh zkServer.sh start
- 检查是否启动:可输入命令:
# jps
查看是否有QuorumPeerMain进程(jps命令用不了是因为没有安装javaJDK或者没有配置环境变量)
也可以zookeeper状态:# sh zkServer.sh status
单机模式状态
- zookeeper在启动之后会在bin目录下生成一个名为zookeeper.out的文件,所以,如果出错,可以查看这个文件看看到底由于什么错误引起的
- 进入客户端:
# sh zkCli.sh
Ctrl+l 可以清屏
- 进入根目录:# ls /
(1) Zookeeper有一个根节点;
(2)每个节点叫znode节点
(3)每个znode节点都有自己的子节点
(4)Zookeerper的所有操作,都是基于节点路径操作的;
(5)多个znode节点共同形成Znode树(整个Zookeeper存储的目录结构)
查看里面的内容使用:# ls /zookeeper
支持补全
(6)创建节点 :# create /park01 "Hello Word"
注意,创建节点必须分配初始数据;如果不想给初始数据,也可以给空 # create /park01 ""
(7)每个Znode节点都可以存储数据
(8)每个Znode节点路径都是唯一的。基于这个特性,我们可以做集群的统一命名服务可以用路径来标识一台服务器;
(9)Znode树是维系在内存中,即znode节点的数据是存在内存中的,目的是供用户快速查询。
(10)不能利用Zookeeper存储海量数据,一是使用场景是做分布式的协调服务,二是基于内存来存储,多台zk节点存储的是同一数据;
(11)Zookeeper也提供了持久化机制,持久化的目录由zoo.cfg中的dataDir来决定;
(12) 查看节点数据:# get /park01
各个参数含义: ctime–创建节点时间戳 mtime–修改节点时间戳
cZxid–创建节点的事务Id,没产生一个事务,zookeeper就
会为这个事务分配一个事务Id,事务Id全局递增,
mZxid–修改节点的事务Id
pZxid–此接待你最新的事务Id
(12)Zookeeper 会为每一个事务分配一个全局事务Id
(13)删除节点:# delete /park01
或者递归删除 :# rmr /park01
(14)创建了临时节点:# create -e /park02 "hello word"
,当创建临时节点的客户端宕机之后,临时节点也会删除;
(15) 创建顺序节点:# create -s /zk "hello"
(16)创建既是临时的,又是顺序的:# create -s -e /zk “hello”;
(17) Zookeeper有四种类型节点:
–create /park01 --create -e /park01 --create -s /park01 --create -e -s/park01
(18).基于临时节点,我们可以应用于检测zookeeper是宕机还是运行二、API操作
package com.Zookeeper;
import org.apache.zookeeper.*;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* APi操作zookeeper
*/
public class TestDemo {
private ZooKeeper zooKeeper;
//连接Zookeeper
@Test
public void connect() throws IOException, InterruptedException {
/**
* 此处传入三个参数第一个是zookeeper服务器地址;
* 第二个是客户端连接服务端超时时间;
* 第三个是监听器Watcher() 接口;
* zookeeper的连接是一个非阻塞连接,底层网络通信用的是netty,框架是NIO;
*/
//闭锁
final CountDownLatch cdl = new CountDownLatch(1);
zooKeeper = new ZooKeeper("192.168.137.154:2181", 30000, new Watcher() {
@Override
public void process(WatchedEvent event) {
/**
* SyncConnected()连接成功事件:判断是否连接成功
*/
if (event.getState().equals(Event.KeeperState.SyncConnected)){
System.out.println("连接成功");
//匿名内部类中只能使用final类型的,所以cdl应该申明为final
cdl.countDown();
}
}
});
cdl.await();
}
//创建节点
@Test
public void create () throws KeeperException, InterruptedException {
zooKeeper.create("/park1","hello".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
//获取节点数据
@Test
public void getData() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/park1",null,null);
System.out.println(new String (data));
}
//更新数据
@Test
public void setData() throws KeeperException, InterruptedException {
//路径+更新的数据+数据版本号(如果写-1表示无论如何都跟新)
zooKeeper.setData("/park1","1804".getBytes(),-1);
}
//删除
@Test
public void deletedata() throws KeeperException, InterruptedException {
zooKeeper.delete("/park1",-1);
}
//获取子节点
@Test
public void getChile() throws KeeperException, InterruptedException {
List<String> paths = zooKeeper.getChildren("/park2",null);
for (String path :paths){
System.out.println(path);
}
}
//监听到节点数据变化事件
@Test
public void WatchDataChange() throws KeeperException, InterruptedException {
for (;;){
//闭锁
final CountDownLatch countDownLatch = new CountDownLatch(1);
zooKeeper.getData("park01", new Watcher() {
@Override
public void process(WatchedEvent event) {
//数据发生变化事件
if (event.getType().equals(Event.EventType.NodeDataChanged)){
System.out.println("数据发生变化了");
countDownLatch.countDown();
try {
//获取数据
zooKeeper.getData("/park01",null,null);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, null);
countDownLatch.await();
}
}
//监听节点被删除事件
@Test
public void WatchDelete() throws KeeperException, InterruptedException {
zooKeeper.exists("/park2", new Watcher() {
@Override
public void process(WatchedEvent event) {
//节点删除时间
if (event.getType().equals(Event.EventType.NodeDeleted)){
System.out.println("节点删除");
}
}
});
while (true);
}
//监听子节点改变事件,监听子节点的创建或删除事件
@Test
public void WatchChileChange() throws KeeperException, InterruptedException {
for (;;){
final CountDownLatch countDownLatch = new CountDownLatch(1);
zooKeeper.getChildren("park01", new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getType().equals(Event.EventType.NodeChildrenChanged)){
System.out.println("子节点改变了");
try {
List<String> paths = zooKeeper.getChildren("/park01",null);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
}
});
countDownLatch.await();
}
}
}