ads:
关注以下公众号查看更多文章
使用docker zookeeper image搭建zooker集群
搭建zookeeper集群,docker-compose.yml文件内容如下
version: '3.1'
services:
zoo1:
image: zookeeper
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo2:
image: zookeeper
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo3:
image: zookeeper
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
networks:
default:
external:
name: zookeeper_cluster2
Java连接Zookeeper集群
可以使用java代码链接到zookeeper集群,进行节点数据的增删改操作,代码如下:
- 引入依赖:implementation 'org.apache.zookeeper:zookeeper:3.4.0'
- Java 代码如下
public static void main(String[] args) throws InterruptedException, KeeperException, IOException {
//连接
CountDownLatch connectedSignal = new CountDownLatch(1);
ZooKeeper zoo;
zoo = new ZooKeeper("mustafa-PC:2181", 5000, new Watcher() {
@Override
public void process(WatchedEvent we) {
if (we.getState() == Event.KeeperState.SyncConnected) {
connectedSignal.countDown();
}
}
});
connectedSignal.await();
//判断节点是否存在
// znode path
String path = "/MyFirstZnode4"; // Assign path to znode
// data in byte array
byte[] data = "My first zookeeper app".getBytes(); // Declare data
Stat stat = zoo.exists(path, true);
if (stat != null) {
System.out.println("Node exists and the node version is " +
stat.getVersion());
final CountDownLatch readedSignal = new CountDownLatch(1);
byte[] b = zoo.getData(path, new Watcher() {
@Override
public void process(WatchedEvent we) {
if (we.getType() == Event.EventType.None) {
switch (we.getState()) {
case Expired:
readedSignal.countDown();
break;
}
} else {
try {
byte[] bn = zoo.getData(path,
false, null);
String data = new String(bn,
"UTF-8");
System.out.println(data);
readedSignal.countDown();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
}, null);
String data2 = new String(b, "UTF-8");
System.out.println(data2);
//修改数据
zoo.setData(path, Long.toString(System.currentTimeMillis()).getBytes(), stat.getVersion());
readedSignal.await();
}else {
zoo.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
zoo.close();
}
Zookeeper核心API:
- zoo.exists 判断节点是否存在
- zoo.getData 获取数据
- zoo.setData 修改数据
- zoo.create 新建数据
Znode的类型
Znode被分为持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点。
-
持久节点 - 即使在创建该特定znode的客户端断开连接后,持久节点仍然存在。默认情况下,除非另有说明,否则所有znode都是持久的。
-
临时节点 - 客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。
-
顺序节点 - 顺序节点可以是持久的或临时的。当一个新的znode被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置znode的路径。例如,如果将具有路径 /myapp 的znode创建为顺序节点,则ZooKeeper会将路径更改为 /myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个znode使用相同的数字。顺序节点在锁定和同步中起重要作用
参考资料: