Zookeeper 介绍与使用
zookeeper是什么
是分布式协调框架,主要解决分布式应用中的数据问题:
- 统一命名服务
- 状态同步
- 集群管理
- 健康检查
- 分布式应用配置等
可以把zookeeper当成一个数据库,不过存储的数量少,并且是基于内存的数据库。
两个核心概念:文件系统数据结构,监听通知机制
安装
# 检查java环境
java -version
# 下载解压zookeeper
wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper‐3.6.3/apache‐zookeeper‐3.6.3‐bin.tar.gz
tar ‐zxvf apache‐zookeeper‐3.6.3‐bin.tar.gz
cd apache‐zookeeper‐3.6.8‐bin
# 重命名配置文件
cp zoo_sample.cfg zoo.cfg
# 启动zookeeper
cd ../bin
./zkServer.sh start
# 检查是否启动成功
./zkServer.sh status
#ZooKeeper JMX enabled by default
#Using config: /data/zookeeper/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
#Client port found: 2181. Client address: localhost.
#Mode: standalone
# 客户端连接
./zkCli.sh
文件系统数据结构
zookeeper文件存储结构类似linux文件系统,每个节点既是一个目录,节点下可以拥有数据部分和子节点
-
持久化目录节点 PERSISTENT
客户端zk断开连接之后,节点仍然会存在。只要不删除就一直会存在
# 创建持久化目录节点 不带任何参数,默认创建持久化节点。节点必须目录必须使用绝对路径 create /aaa 123 #创建持久化节点/aaa 值是123 get /aaa #获取/aaa 节点的值 set /aaa 456 #修改/aaa 节点的值 delete /aaa #删除/aaa 节点。如果节点下有子节点,是不能删除的 create /aaa/bbb 456 #创建/aaa的子节点bbb 值是456 create /aaa/ccc 456 create /aaa/bbb/ddd 456 ls /aaa #查看/aaa 下的子节点列表 ls -R /aaa #递归查看/aaa 下的子节点列表 deleteall /aaa #删除/aaa节点及所有子节点
-
持久化顺序编号目录节点 PERSISTENT_SEQUENTIAL
创建顺序节点默认会创建一个编号,顺序递增
[zk: localhost:2181(CONNECTED) 16] create /ss Created /ss [zk: localhost:2181(CONNECTED) 17] create -s /ss/ss 123 Created /ss/ss0000000000 [zk: localhost:2181(CONNECTED) 18] create -s /ss/ss 456 Created /ss/ss0000000001 [zk: localhost:2181(CONNECTED) 19] create -s /ss/ss 789 Created /ss/ss0000000002 [zk: localhost:2181(CONNECTED) 20] create -s /ss/ss 1000 Created /ss/ss0000000003 [zk: localhost:2181(CONNECTED) 21] create /ss
-
临时目录节点 EPHEMERAL
当客户端主动和zk主动断开连接之后,会立刻删除临时节点。
临时节点下不可以创建新的节点
create -e /eee 123 create /aaa create -e /aaa/eee #在持久化节点/aaa 创建临时节点eee
-
临时顺序编号目录节点 EPHEMERAL_SEQUENTIAL
和持久化顺序节点类似
-
容器节点 Container
如果容器节点下新增子节点并且删除,zk会有个定时任务(默认60s检查一次),清除容器节点
create -c /ccc
-
TTL节点
默认禁用,启动时增加配置zookeeper.extendedTypesEnabled=true,指定时间内没有修改节点数据,就会被清除,但不稳定
节点状态 stat /aaa
cZxid:创建znode的事务ID(Zxid的值)。
mZxid:最后修改znode的事务ID。
pZxid:最后添加或删除子节点的事务ID(子节点列表发生变化才会发生改变)。
ctime:znode创建时间。
mtime:znode最近修改时间。
dataVersion:znode的当前数据版本。
cversion:znode的子节点结果集版本(一个节点的子节点增加、删除都会影响这个
版本)。
aclVersion:表示对此znode的acl版本。
ephemeralOwner:znode是临时znode时,表示znode所有者的 session ID。 如果
znode不是临时znode,则该字段设置为零。
dataLength:znode数据字段的长度。
numChildren:znode的子znode的数量。
监听通知机制
客户端可以创建监听器,监听节点发生的变化。可以监听节点本身及子节点的所有变化
使用java客户端连接zookeeper
public static void main(String[] args) throws Exception {
//重试策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
// 建立客户端
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("192.168.10.102:2181")
.sessionTimeoutMs(60 * 1000) // 会话超时时间
.connectionTimeoutMs(5000) // 连接超时时间
.retryPolicy(retryPolicy)
.build();
client.start();
//创建节点
//System.out.println(client.create().forPath("/curator", "123".getBytes()));
//子节点
//System.out.println(client.create().forPath("/curator/test1", "123".getBytes()));
//临时节点
//System.out.println(client.create().withMode(CreateMode.EPHEMERAL).forPath("/curator/test1/eee", "123".getBytes()));
//创建监听器
CuratorCacheListener listener = CuratorCacheListener.builder()
//监听节点的创建,和子节点的创建
.forCreates(System.out::println)
//监听节点的内容的改变,和子节点内容的改变
.forChanges((oldNode, node) -> System.out.println("oldNode:" + oldNode + " node:" + node))
//监听节点的删除,和子节点的删除
.forDeletes(System.out::println)
.forInitialized(() -> {
//监听器初始化
System.out.println("listener init...");
})
.build();
//将zk目录下的数据缓存在本地
CuratorCache cache = CuratorCache.build(client, "/aaa");
//添加目录下的监听器
cache.listenable().addListener(CuratorCacheListener.builder().forAll(listener).build());
cache.start();
System.in.read();
}