1.Zookeeper应用场景
## 2.Zookeeper数据结构
3.Zookeeperan安装
1.上传zk并且解压
cd /usr/local/
tar -zxvf zookeeper-3.4.6.tar.gz
mv zookeeper-3.4.6 zookeeper
2.修改zookeeper环境变量
vi /etc/profile
export ZOOKEEPER_HOME=/usr/local/zookeeper
source /etc/profile
3.修改zoo_sample.cfg文件
cd /usr/local/zookeeper/conf
mv zoo_sample.cfg zoo.cfg
修改conf: vi zoo.cfg
dataDir=/usr/local/zookeeper/data(注意同时在zookeeper创建data目录)
4.启动zookeeper
路径:cd /usr/local/zookeeper/bin
执行:./ zkServer.sh start
查询状态: ./zkServer.sh status
4.Java操作Zookeeper
Zookeeper说明
创建节点(znode) 方法:
create:
提供了两套创建节点的方法,同步和异步创建节点方式。
同步方式:
参数1,节点路径《名称) : InodeName (不允许递归创建节点,也就是说在父节点不存在
的情况下,不允许创建子节点)
参数2,节点内容: 要求类型是字节数组(也就是说,不支持序列化方式,如果需要实现序
列化,可使用java相关序列化框架,如Hessian、Kryo框架)
参數3,节点权限: 使用Ids.OPEN_ACL_UNSAFE开放权限即可。(这个参数一般在权展
没有太高要求的场景下,没必要关注)
参数4,节点类型: 创建节点的类型: CreateMode,提供四种首点象型
PERSISTENT 持久化节点
PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1
EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除
EPHEMERAL_SEQUENTIAL 临时自动编号节点
Watcher
在ZooKeeper中,接口类Watcher用于表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含KeeperState和EventType两个枚举类,分别代表了通知状态和事件类型,同时定义了事件的回调process(WatchedEvent event)。
什么是Watcher接口?
同一个事件类型在不同的通知状态中代表的含义有所不同,列举了常见的通知状态和事件类型。
Watcher通知状态与事件类型一览
ZooKeeper创建修改删除节点实现
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @author Administrator
*/
public class ZooKeeperTest {
/**
* 连接地址
*/
private static final String ZOOKEEPER_ADDRESS = "192.168.223.120:2181";
/**
* session 会话
*/
private static final int SESSION_OUT = 30000;
/**
* 信号量,阻塞程序执行,用户等待zookeeper连接成功,发送成功信号,
*/
private static CountDownLatch countDownLatch = new CountDownLatch(1);
/**
* 创建节点路径
*/
private static String LOG_MAIN = "/rootNode";
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zooKeeper = new ZooKeeper(ZOOKEEPER_ADDRESS, SESSION_OUT, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
// 通知状态
Event.KeeperState keeperState = watchedEvent.getState();
// 事件类型
Event.EventType eventType = watchedEvent.getType();
// 获取Zk路径
String path = watchedEvent.getPath();
if (Event.KeeperState.SyncConnected == keeperState) {
if (Event.EventType.None == eventType) {
countDownLatch.countDown();
System.out.println("已经建立了连接");
} else if (Event.EventType.NodeCreated == eventType) {
System.out.println("节点创建:" + path);
} else if (Event.EventType.NodeDataChanged == eventType) {
System.out.println("节点修改:" + path);
} else if (Event.EventType.NodeDeleted == eventType) {
System.out.println("节点删除:" + path);
}
}
}
});
countDownLatch.await();
createRootPath(zooKeeper);
setRootPath(zooKeeper);
deleteRootPath(zooKeeper);
}
public static void createRootPath(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
/**
* CreateMode四种节点类型
* PERSISTENT 持久化节点
* PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1
* EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除
* EPHEMERAL_SEQUENTIAL 临时自动编号节点
*/
zooKeeper.exists(LOG_MAIN, true);
zooKeeper.create(LOG_MAIN, LOG_MAIN.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public static void setRootPath(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
// exists() 方法如果路径删除成功,true 表示会调用监听事件
zooKeeper.exists(LOG_MAIN, true);
zooKeeper.setData(LOG_MAIN, "root".getBytes(), -1);
}
public static void deleteRootPath(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
// exists() 方法如果路径删除成功,true 表示会调用监听事件
zooKeeper.exists(LOG_MAIN, true);
zooKeeper.delete(LOG_MAIN, 1);
}
}
结果