Zookeeper Java 设置节点

下面将介绍怎样使用 ZooKeeper 类来设置已存在节点的数据。

方法说明

在 ZooKeeper 类中,使用  setData 方法修改节点中的内容,方法签名如下:

  • Stat setData(String path, byte[] data, int version)  同步版本

  • void setData(String path, byte[] data, int version, AsyncCallback.StatCallback cb, Object ctx)  异步版本

如果存在给定路径的节点,且给定版本与该节点的版本相匹配,则为该节点设置数据(如果给定版本为-1,则与任何节点的版本相匹配)。

此操作如果成功,将触发 getData 调用对给定路径的节点注册的所有监视(watche)。

如果不存在给定路径的节点,将抛出错误代码为 KeeperException.NoNode 的 KeeperException 异常。

如果给定的版本与节点的版本不匹配,将抛出错误代码为 KeeperException.BadVersion 的 KeeperException 异常。

数据数组的最大允许大小为 1 MB(1,048,576 字节)。大于此值的数组将引发 KeeperException 异常。

参数说明:

  • path - 节点路径

  • data - 节点新的数据

  • version - 期望的匹配版本

  • cb - 异步调用的回调接口

  • ctx - 扩展数据

完整示例

下面通过完整示例演示 setData 同步版本和异步版本的用法,代码如下:

package com.hxstrive.zookeeper;

import com.alibaba.fastjson.JSONObject;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * 设置节点数据
 * @author hxstrive.com
 */
public class SetDataNode {
    private static ZooKeeper zooKeeper;

    @Before
    public void init() throws Exception {
        zooKeeper = new ZooKeeper("127.0.0.1:2181", 2000, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                System.out.println("触发了 " + watchedEvent.getType() + " 事件");
            }
        });

        // 如果节点不存在,则创建节点
        Stat stat = zooKeeper.exists("/setData_node", false);
        if(null == stat) {
            String nodeName = zooKeeper.create("/setData_node", "init value".getBytes(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("nodeName = " + nodeName);
        }
    }

    /**
     * 同步设置节点数据
     */
    @Test
    public void syncDemo() throws Exception {
        Stat stat = zooKeeper.setData("/setData_node", "new data".getBytes(), -1);
        System.out.println("cZxid = " + stat.getCzxid()); // 节点被创建时的事务ID
        System.out.println("ctime = " + stat.getCtime()); // 节点创建时间
        System.out.println("mZxid = " + stat.getMzxid()); // 最近一次更新时的事务ID
        System.out.println("mtime = " + stat.getMtime()); // 最近一次更新时间
        System.out.println("pZxid = " + stat.getPzxid()); // 该节点的子节点列表最近一次被修改的事务ID,添加、删除子节点会影响该值
        System.out.println("cversion = " + stat.getCversion()); // 子节点版本号
        System.out.println("dataLength = " + stat.getDataLength()); // 当前节点的数据长度
        System.out.println("numChildren = " + stat.getNumChildren()); // 当前节点的子节点数目
        System.out.println("dataVersion = " + stat.getVersion()); // 数据版本号
        System.out.println("aclVersion = " + stat.getAversion()); // ACL版本号
        //输出:
        //触发了 None 事件
        //nodeName = /setData_node
        //cZxid = 181
        //ctime = 1703686343414
        //mZxid = 182
        //mtime = 1703686343421
        //pZxid = 181
        //cversion = 0
        //dataLength = 8
        //numChildren = 0
        //dataVersion = 1
        //aclVersion = 0
    }

    /**
     * 异步设置节点数据
     */
    @Test
    public void asyncDemo() throws Exception {
        Map<String,String> extData = new HashMap<>();
        extData.put("code", "C100");
        extData.put("title", "这是标题");

        // 这里的 CountDownLatch 仅仅是为了能够等待 AsyncCallback.StatCallback
        CountDownLatch countDownLatch = new CountDownLatch(1);
        zooKeeper.setData("/setData_node", "new data".getBytes(), -1,
                // 回调接口实现
                new AsyncCallback.StatCallback() {
                    @Override
                    public void processResult(int i, String s, Object o, Stat stat) {
                        System.out.println("i = " + i);
                        System.out.println("s = " + s);
                        System.out.println("o = " + o); // 扩展数据
                        System.out.println("stat = " + JSONObject.toJSONString(stat));
                        countDownLatch.countDown();
                    }
                },
                // 传递扩展数据,可以在回调 processResult 方法中获取到
                extData);

        countDownLatch.await();
        //输出:
        //触发了 None 事件
        //i = 0
        //s = /setData_node
        //o = {code=C100, title=这是标题}
        //stat = {"aversion":0,"ctime":1703686343414,"cversion":0,"czxid":181,"dataLength":8,"ephemeralOwner":0,
        // "mtime":1703686374532,"mzxid":185,"numChildren":0,"pzxid":181,"version":2}
    }

}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号