Zookeeper 是一个分布式协调服务,常用于分布式应用程序中,提供一致性、高可用性和可靠性。Zookeeper 的架构主要由以下几个部分组成:
-
客户端(Client):
- 客户端是与 Zookeeper 服务器进行交互的实体。客户端通过 Zookeeper API 进行连接、读写数据和注册 Watcher 等操作。
-
服务器(Server):
- Zookeeper 集群中的每个节点都是一个服务器。服务器有三种角色:Leader、Follower 和 Observer。
-
Leader:
- Leader 是 Zookeeper 集群中的核心节点,负责处理所有写请求和协调事务的提交。Leader 通过 Zab(Zookeeper Atomic Broadcast)协议与 Follower 进行通信,确保数据的一致性。
-
Follower:
- Follower 是 Zookeeper 集群中的从节点,负责处理读请求和转发写请求给 Leader。此外,Follower 还参与选举 Leader 和同步数据。
-
Observer:
- Observer 是一种特殊的节点,主要用于扩展集群的读取能力。Observer 不参与 Leader 选举和事务提交,只负责处理读请求。
-
数据节点(ZNode):
- ZNode 是 Zookeeper 中的数据存储单元。每个 ZNode 都有一个唯一的路径,可以存储数据和子节点。ZNode 分为持久节点和临时节点。
Zookeeper 的架构组成图示
+-------------------+
| Clients |
+-------------------+
|
v
+-------------------+
| Zookeeper |
| Ensemble |
| |
| +-----------+ |
| | Leader | |
| +-----------+ |
| / \ |
| / \ |
| v v |
| +---------+ +---------+
| | Follower | | Follower |
| +---------+ +---------+
| / \ / \
| v v v v
| +---------+ +---------+
| | Observer | | Observer |
| +---------+ +---------+
+-------------------+
代码示例
以下代码示例展示了如何使用 Zookeeper 客户端连接 Zookeeper 集群并进行基本操作。
1. 添加 Maven 依赖
在 pom.xml 中添加 Zookeeper 客户端的依赖:
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.3</version>
</dependency>
2. 创建 Zookeeper 客户端并进行基本操作
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
public class ZookeeperClientExample {
private static final String ZK_ADDRESS = "localhost:2181";
private static final int SESSION_TIMEOUT = 3000;
private ZooKeeper zooKeeper;
public void connect() throws IOException {
zooKeeper = new ZooKeeper(ZK_ADDRESS, SESSION_TIMEOUT, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.SyncConnected) {
System.out.println("Successfully connected to Zookeeper");
}
}
});
}
public void createNode(String path, byte[] data) throws KeeperException, InterruptedException {
zooKeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public byte[] getNodeData(String path) throws KeeperException, InterruptedException {
return zooKeeper.getData(path, false, null);
}
public void updateNodeData(String path, byte[] data) throws KeeperException, InterruptedException {
zooKeeper.setData(path, data, -1);
}
public void deleteNode(String path) throws KeeperException, InterruptedException {
zooKeeper.delete(path, -1);
}
public void close() throws InterruptedException {
if (zooKeeper != null) {
zooKeeper.close();
}
}
public static void main(String[] args) throws Exception {
ZookeeperClientExample client = new ZookeeperClientExample();
client.connect();
String path = "/example_node";
byte[] data = "Hello Zookeeper".getBytes();
// Create node
client.createNode(path, data);
// Retrieve and print node data
byte[] retrievedData = client.getNodeData(path);
System.out.println("Data of node " + path + ": " + new String(retrievedData));
// Update node data
byte[] newData = "Updated data".getBytes();
client.updateNodeData(path, newData);
// Retrieve and print updated node data
byte[] updatedData = client.getNodeData(path);
System.out.println("Updated data of node " + path + ": " + new String(updatedData));
// Delete node
client.deleteNode(path);
client.close();
}
}
详细解释
-
连接 Zookeeper:
- 在
connect方法中,创建一个新的 Zookeeper 客户端实例,并通过 Watcher 监听连接状态。
- 在
-
创建节点:
- 在
createNode方法中,使用zooKeeper.create方法创建一个新的节点。ZooDefs.Ids.OPEN_ACL_UNSAFE表示不安全的 ACL(任何人都可以访问),CreateMode.PERSISTENT表示持久节点。
- 在
-
读取节点数据:
- 在
getNodeData方法中,使用zooKeeper.getData方法读取节点数据。
- 在
-
更新节点数据:
- 在
updateNodeData方法中,使用zooKeeper.setData方法更新节点数据。
- 在
-
删除节点:
- 在
deleteNode方法中,使用zooKeeper.delete方法删除节点。
- 在
-
关闭连接:
- 在
close方法中,关闭 Zookeeper 客户端连接。
- 在
总结
Zookeeper 的架构主要由客户端、服务器(包括 Leader、Follower 和 Observer)以及数据节点(ZNode)组成。通过上述代码示例,可以了解如何使用 Zookeeper 客户端连接 Zookeeper 集群并进行基本的节点创建、读取、更新和删除操作。