ZooKeeper
下载安装配置
下载地址:Apache ZooKeeper
下载完成后上传的Linux的/opt/zookeeper目录下
//可能用到的Linux命令
mkdir zookeeper //创建zookeeper目录
//将压缩包进行解压
tar -zxvf appache-ZooKeeper-3.7.2-bin.tar.gz
配置
#进入conf目录
cd /opt/zookeeper/appache-ZooKeeper-3.7.2-bin/conf/
#拷贝
cp zoo_sample.cfg zoo.cfg
#修改zoo.cfg
cd /opt/zookeeper/
mkdir zkdata
vi /opt/zookeeper/appache-ZooKeeper-3.7.2-bin/conf/zoo.cfg
#修改存储目录
dataDir=/opt/zookeeper/zkdata
启动Zookeeper
cd /opt/zookeeper/appache-ZooKeeper-3.7.2-bin/bin/
#启动
./zkServer.sh start
#查看状态
./zkServer.sh status
节点可以分为四大类:
PERSISTENT 持久化节点
EPHEMERAL 临时节点 :-e
PERSISTENT_SEQUENTIAL 持久化顺序节点 :-s
EPHEMERAL_SEQUENTIAL 临时顺序节点 :-es
服务端常用命令:
•启动 ZooKeeper 服务: ./zkServer.sh start
•查看 ZooKeeper 服务状态: ./zkServer.sh status
•停止 ZooKeeper 服务: ./zkServer.sh stop
•重启 ZooKeeper 服务: ./zkServer.sh restart
客户端常用命令:
#连接zookeeper服务端
./zkcli.sh -server ip:port
#断开连接
quit
#显示指定目录的节点
ls 目录
#创建节点
create /节点
#获取节点值
get /节点
#设置结点的值
set /节点 value
#删除单个节点
delete /节点
#删除带有子节点的节点
deleteall /节点
#创建临时节点
create -e /节点 value
#创建顺序节点
create -s /节点 value
#查询节点详细信息
ls -s /节点
•czxid:节点被创建的事务ID
•ctime: 创建时间
•mzxid: 最后一次被更新的事务ID
•mtime: 修改时间
•pzxid:子节点列表最后一次被更新的事务ID
•cversion:子节点的版本号
•dataversion:数据版本号
•aclversion:权限版本号
•ephemeralOwner:用于临时节点,代表临时节点的事务ID,如果为持久节点则为0
•dataLength:节点存储的数据的长度
•numChildren:当前节点的子节点个数
JavaAPI操作
引入坐标
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
package com.buka;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class TestConnect {
public static CuratorFramework client;
public void testConnect(){
// 当与ZooKeeper的某个操作失败时,首先等待3000毫秒(或3秒)进行第一次重试,
// 如果仍然失败,则等待更长的时间(基于指数退避算法)进行第二次重试,
// 依此类推,直到达到最大重试次数10次。如果在这10次重试之后操作仍然失败,那么会抛出一个异常
RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
client = CuratorFrameworkFactory.builder()
.connectString("192.168.128.2:2181")
.sessionTimeoutMs(60*1000)
.retryPolicy(retryPolicy)
.namespace("buka")
.build();
client.start();
}
}
创建节点
public class Main {
public static void main(String[] args) throws Exception {
TestConnect test = new TestConnect();
test.testConnect();
testCreate();
}
public static void testCreate() throws Exception {
//持久化节点(如果没有指定数据,默认将当前客户端的ip地址作为数据存储)
String path = TestConnect.client.create().forPath("/app", "hello".getBytes());
System.out.println(path);
}
public static void testCreate1() throws Exception {
//临时节点(客户端断开连接,数据自动删除,如果没有指定数据,默认将当前客户端的ip地址作为数据存储,withMode选择模式,CreateMode枚举类型)
String path1 = TestConnect.client.create().withMode(CreateMode.EPHEMERAL).forPath("/app1", "hello".getBytes());
System.out.println(path1);
}
public static void testCreate2() throws Exception {
//临时顺序节点(客户端断开连接,数据自动删除,如果没有指定数据,默认将当前客户端的ip地址作为数据存储,withMode选择模式,CreateMode枚举类型)
String path2 = TestConnect.client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/app1", "hello".getBytes());
System.out.println(path2);
}
public static void testCreate3() throws Exception {
//如果没有父节点,则创建父节点
String path = TestConnect.client.create().creatingParentsIfNeeded().forPath("/app5/app1", "hello".getBytes());
System.out.println(path);
}
}
查询节点
package com.buka;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
TestConnect test = new TestConnect();
test.testConnect();
set1()
}
// 查询节点数据
public static void set1() throws Exception {
byte[] bytes = TestConnect.client.getData().forPath("/app");
System.out.println(new String(bytes));
}
// 查询子节点
public static void set2() throws Exception {
List<String> path = TestConnect.client.getChildren().forPath("/");
for (String s : path) {
System.out.println(s);
}
}
// 查询节点状态
public static void set3() throws Exception {
Stat stats = new Stat();
System.out.println(stats);
TestConnect.client.getData().storingStatIn(stats).forPath("/");
System.out.println(stats);
long czxid = stats.getCzxid();
System.out.println(czxid);
}
}
修改节点
public class Main {
public static void main(String[] args) throws Exception {
TestConnect test = new TestConnect();
test.testConnect();
}
// 修改节点数据
public static void update1() throws Exception {
TestConnect.client.setData().forPath("/app1","nihao".getBytes());
}
public static void update2() throws Exception {
/**
* 首先读取ZooKeeper中/app节点的数据和元数据,然后打印出该节点的版本信息,
* 并尝试更新该节点的数据,但只在当前版本与读取到的版本匹配时才进行更新。
*/
Stat stats = new Stat();
TestConnect.client.getData().storingStatIn(stats).forPath("/app");
int version = stats.getVersion();
System.out.println(version);
TestConnect.client.setData().withVersion(version).forPath("/app", "buka1".getBytes());
}
}
删除节点
package com.buka;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
TestConnect test = new TestConnect();
test.testConnect();
testDelete3();
}
// 删除节点
public static void testDelete() throws Exception {
TestConnect.client.delete().forPath("/app5/app1");
}
// 删除带有子节点的
public static void testDelete1() throws Exception {
TestConnect.client.delete().deletingChildrenIfNeeded().forPath("/app5");
}
// 必须删除成功,就算网络波动大,也一定保证成功
public static void testDelete2() throws Exception {
TestConnect.client.delete().guaranteed().forPath("/app5");
}
// 回调
public static void testDelete3() throws Exception {
TestConnect.client.delete().guaranteed().inBackground(new BackgroundCallback() {
@Override
public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
System.out.println("删除成功");
}
}).forPath("/app5");
TestConnect.client.close();
}
}