Zookeeper(12)Zookeeper的临时节点和持久节点有什么区别?

190 阅读3分钟

Zookeeper 的节点类型主要分为两类:持久节点(Persistent)和临时节点(Ephemeral)。这两种节点类型在生命周期、用途和行为上有显著区别。以下是详细的对比和代码示例。

持久节点(Persistent)和临时节点(Ephemeral)的区别

  1. 生命周期

    • 持久节点:节点在创建后会一直存在,直到被显式删除。即使创建该节点的客户端断开连接,节点仍然存在。
    • 临时节点:节点在创建后会与客户端会话绑定,当会话结束(如客户端断开连接)时,节点会被自动删除。
  2. 用途

    • 持久节点:用于存储需要长期存在的数据,如配置数据、元数据等。
    • 临时节点:用于存储临时数据,如会话数据、临时配置等,特别适用于需要反映客户端会话状态的场景,如分布式锁、主选举等。
  3. 节点行为

    • 持久节点:可以被多个客户端读取和修改,适用于共享数据。
    • 临时节点:只能由创建它的客户端删除或修改,其存在与否直接反映了客户端的连接状态。

代码示例

以下代码示例展示了如何在 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.ZooKeeper;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;

public class ZookeeperClient {
    private static final String ZK_ADDRESS = "localhost:2181";
    private static final int SESSION_TIMEOUT = 3000;

    private ZooKeeper zooKeeper;

    public void connect() throws Exception {
        zooKeeper = new ZooKeeper(ZK_ADDRESS, SESSION_TIMEOUT, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("Event received: " + event);
            }
        });
    }

    public void close() throws InterruptedException {
        if (zooKeeper != null) {
            zooKeeper.close();
        }
    }

    public ZooKeeper getZooKeeper() {
        return zooKeeper;
    }
}

3. 创建持久节点和临时节点

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class ZookeeperNodeExample {
    private static final String PERSISTENT_PATH = "/persistent_node";
    private static final String EPHEMERAL_PATH = "/ephemeral_node";

    public static void main(String[] args) throws Exception {
        ZookeeperClient client = new ZookeeperClient();
        client.connect();
        ZooKeeper zooKeeper = client.getZooKeeper();

        // 创建持久节点
        if (zooKeeper.exists(PERSISTENT_PATH, false) == null) {
            String createdPath = zooKeeper.create(PERSISTENT_PATH, "persistent_data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("Created persistent node path: " + createdPath);
        }

        // 创建临时节点
        if (zooKeeper.exists(EPHEMERAL_PATH, false) == null) {
            String createdPath = zooKeeper.create(EPHEMERAL_PATH, "ephemeral_data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            System.out.println("Created ephemeral node path: " + createdPath);
        }

        // 读取持久节点数据
        byte[] persistentData = zooKeeper.getData(PERSISTENT_PATH, false, null);
        System.out.println("Persistent node data: " + new String(persistentData));

        // 读取临时节点数据
        byte[] ephemeralData = zooKeeper.getData(EPHEMERAL_PATH, false, null);
        System.out.println("Ephemeral node data: " + new String(ephemeralData));

        // 关闭客户端,触发临时节点删除
        client.close();

        // 等待一段时间,确保会话结束
        Thread.sleep(5000);

        // 重新连接 Zookeeper
        client.connect();
        zooKeeper = client.getZooKeeper();

        // 检查持久节点是否存在
        Stat persistentStat = zooKeeper.exists(PERSISTENT_PATH, false);
        System.out.println("Persistent node exists: " + (persistentStat != null));

        // 检查临时节点是否存在
        Stat ephemeralStat = zooKeeper.exists(EPHEMERAL_PATH, false);
        System.out.println("Ephemeral node exists: " + (ephemeralStat != null));

        client.close();
    }
}

详细解释

  1. 持久节点创建和使用

    • 使用 CreateMode.PERSISTENT 创建持久节点。
    • 创建了路径为 /persistent_node 的持久节点,并写入了数据 "persistent_data"
    • 读取持久节点的数据并打印。
  2. 临时节点创建和使用

    • 使用 CreateMode.EPHEMERAL 创建临时节点。
    • 创建了路径为 /ephemeral_node 的临时节点,并写入了数据 "ephemeral_data"
    • 读取临时节点的数据并打印。
  3. 会话结束后的节点检查

    • 关闭客户端连接,触发临时节点删除。
    • 重新连接 Zookeeper,并检查持久节点和临时节点是否存在。
    • 打印结果,验证持久节点仍然存在,而临时节点已被删除。

总结

持久节点和临时节点在 Zookeeper 中有不同的生命周期和用途。持久节点在创建后会一直存在,适用于存储长期数据;而临时节点会在客户端会话结束时自动删除,适用于存储临时数据。通过上述代码示例,可以直观地了解两种节点类型的创建、使用和行为差异。了解这些区别,有助于在实际应用中选择合适的节点类型来满足不同的需求。