ZooKeeper API操作

ZooKeeper集群中,客户端可以对ZooKeeper的命名空间写入数据,对数据进行各种操作。ZooKeeper API 接口如下表所示:


操作接口名称 描述
create 创建指定的ZooKeeper命名空间(PATH)数据。
delete 创建指定的ZooKeeper命名空间(PATH)数据。
exists 检测节点是否存在
getChildren 获取节点孩子列表
getData 获取指定节点数据
setData 设置指定节点的数据
getACL 获取节点的ACL
setACL 设置节点的ACL
sync 同步一个客户视图到ZooKeeper中

1.4.1 增删改查

给指定ZooKeeper命名空间创建节点,你可以扩展ZooKeeper类。你可以定义类ZooKeeperRetry,然后定义构造方法。

/**
 * @param connectString ZooKeeper‘s host and port 字符串表达 
 * @param sessionTimeout 连接超时时间
 * @param watcher    观察者对象
 * @throws IOException
 */
public ZooKeeperRetry(String connectString, int sessionTimeout,
        Watcher watcher) throws IOException {
    super(connectString, sessionTimeout, watcher);
    this.watcher = watcher;
}

复写ZooKeeper类的方法。对于添加操作API,复写对应的create方法,定义个性化地创建节点操作。

@Override
public String create(String path, byte[] data, List<ACL> acl,
        CreateMode createMode) throws KeeperException, InterruptedException {
    int count = 0;
    do {
        try {
            return super.create(path, data, acl, createMode);
        } catch (KeeperException.ConnectionLossException e) {
            LoggerFactory.getLogger().warn(
                    "ZooKeeper connection lost.  Trying to reconnect.");
            if (exists(path, false) != null) {
                return path;
            }
        } catch (KeeperException.NodeExistsException e) {
            return path;
        }
    } while (!closed && (limit == -1 || count++ < limit));
    return null;
}

对于修改操作,使用创建方法去完成更新,即存在的节点内容被新节点信息所覆盖。对于删除操作,直接复写ZooKeeper的delete方法,下面的代码实现了删除节点操作。如果操作失败,它会自动重复尝试3次,直到成功为止。

/**
 *
 * @param path
 *                the path of the node to be deleted.
 * @param version
 *                the expected node version.
 * @throws InterruptedException
 * @throws KeeperException
 */
@Override
public void delete(String path, int version) throws InterruptedException,
        KeeperException {
    int count = 0;
    do {
        try {
            super.delete(path, version);
        } catch (KeeperException.ConnectionLossException e) {
            LoggerFactory.getLogger().warn(
                    "ZooKeeper connection lost.  Trying to reconnect.");
            if (exists(path, false) == null) {
                return;
            }
        } catch (KeeperException.NoNodeException e) {
            break;
        }
    } while (!closed && (limit == -1 || count++ < limit));
}

为了加深理解,下面将给一个例子。
建立一个maven项目,添加下面的maven依赖配置。

<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-framework</artifactId>
  <version>2.9.1</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-recipes</artifactId>
  <version>2.9.1</version>
</dependency>
  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-client</artifactId>
      <version>2.9.1</version>
  </dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
  <exclusions>
    <exclusion>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
    </exclusion>
    <exclusion>
      <groupId>javax.jms</groupId>
      <artifactId>jms</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jdmk</groupId>
      <artifactId>jmxtools</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jmx</groupId>
      <artifactId>jmxri</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.4.6</version>
  <exclusions>
    <exclusion>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.9.6</version>
</dependency>

定义ZooKeeper的扩展类ZooKeeperRobot类,文件代码如下所示:

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.inspector.logger.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * A Class which extends {@link ZooKeeper} and will automatically retry calls to
 * zookeeper if a {@link KeeperException.ConnectionLossException} occurs
 */
public class ZooKeeperRobot extends ZooKeeper {

    private boolean closed = false;
    private final Watcher watcher;
    private int limit = -1;

    /**
     * @param connectString ZooKeeper‘s host and port 字符串表达
     * @param sessionTimeout 连接超时时间
     * @param watcher    观察者对象
     * @throws IOException
     */
    public ZooKeeperRobot(String connectString, int sessionTimeout,
                          Watcher watcher) throws IOException {
        super(connectString, sessionTimeout, watcher);
        this.watcher = watcher;
    }

    /**
     * @param connectString
     * @param sessionTimeout
     * @param watcher
     * @param sessionId
     * @param sessionPasswd
     * @throws IOException
     */
    public ZooKeeperRobot(String connectString, int sessionTimeout,
                          Watcher watcher, long sessionId, byte[] sessionPasswd)
            throws IOException {
        super(connectString, sessionTimeout, watcher, sessionId, sessionPasswd);
        this.watcher = watcher;
    }

    @Override
    public synchronized void close() throws InterruptedException {
        this.closed = true;
        super.close();
    }

    /**
     *      * @param path
     *                the path for the node
     * @param data
     *                the initial data for the node
     * @param acl
     *                the acl for the node
     * @param createMode
     *                specifying whether the node to be created is ephemeral
     *                and/or sequential
     * @return the actual path of the created node
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Override
    public String create(String path, byte[] data, List<ACL> acl,
            CreateMode createMode) throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.create(path, data, acl, createMode);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect."+e.getMessage());
                if (exists(path, false) != null) {
                    return path;
                }
            } catch (KeeperException.NodeExistsException e) {
                LoggerFactory.getLogger().warn(
                        "NodeExistsException:."+e.getMessage());
                return path;
            }catch(KeeperException.NoNodeException e){
                LoggerFactory.getLogger().warn(
                        "NoNodeException:."+e.getMessage());
                return path;
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }


    /**
     *      * @param path
     *                the path for the node
     * @param data
     *                the initial data for the node
     * @param acl
     *                the acl for the node
     * @param createMode
     *                specifying whether the node to be created is ephemeral
     *                and/or sequential
     * @return the actual path of the created node
     * @throws KeeperException
     * @throws InterruptedException
     */
    public String createPersistent(String path, byte[] data, List<ACL> acl,
                         CreateMode createMode) throws KeeperException, InterruptedException {
        int count = 0;
        String[] partsPath = path.split("/");
        int checkSize = partsPath.length - 1;
        for(int i = 0; i< checkSize; i++){
            String prefixMark = "";
            for(int j = 0; j <= i; j++){
                prefixMark += partsPath[j] + "/";
            }
            if(prefixMark.length() != 1){
                prefixMark = prefixMark.substring(0, prefixMark.length()-1);
                if(exists(prefixMark, false) == null){
                    LoggerFactory.getLogger().warn("create namespace: " + super.create(prefixMark, "".getBytes(), acl, createMode));
                }
            }
        }
        do {
            try {
                return super.create(path, data, acl, createMode);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect."+e.getMessage());
                if (exists(path, false) != null) {
                    return path;
                }
            } catch (KeeperException.NodeExistsException e) {
                LoggerFactory.getLogger().warn(
                        "NodeExistsException:."+e.getMessage());
                return path;
            }catch(KeeperException.NoNodeException e){
                LoggerFactory.getLogger().warn(
                        "NoNodeException:."+e.getMessage());
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }
    /**
     *
     * @param path
     *                the path of the node to be deleted.
     * @param version
     *                the expected node version.
     * @throws InterruptedException
     * @throws KeeperException
     */
    @Override
    public void delete(String path, int version) throws InterruptedException,
            KeeperException {
        int count = 0;
        do {
            try {
                super.delete(path, version);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
                if (exists(path, false) == null) {
                    return;
                }
            } catch (KeeperException.NoNodeException e) {
                break;
            }
        } while (!closed && (limit == -1 || count++ < limit));
    }

    @Override
    public Stat exists(String path, boolean watch) throws KeeperException,
            InterruptedException {
        int count = 0;
        do {
            try {
                return super.exists(path, watch ? watcher : null);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    @Override
    public Stat exists(String path, Watcher watcher) throws KeeperException,
            InterruptedException {
        int count = 0;
        do {
            try {
                return super.exists(path, watcher);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    @Override
    public List<ACL> getACL(String path, Stat stat) throws KeeperException,
            InterruptedException {
        int count = 0;
        do {
            try {
                return super.getACL(path, stat);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    @Override
    public List<String> getChildren(String path, boolean watch)
            throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.getChildren(path, watch ? watcher : null);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return new ArrayList<String>();
    }

    @Override
    public List<String> getChildren(String path, Watcher watcher)
            throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.getChildren(path, watcher);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return new ArrayList<String>();
    }

    @Override
    public byte[] getData(String path, boolean watch, Stat stat)
            throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.getData(path, watch ? watcher : null, stat);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    @Override
    public byte[] getData(String path, Watcher watcher, Stat stat)
            throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.getData(path, watcher, stat);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    @Override
    public Stat setACL(String path, List<ACL> acl, int version)
            throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.setACL(path, acl, version);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
                Stat s = exists(path, false);
                if (s != null) {
                    if (getACL(path, s).equals(acl)) {
                        return s;
                    }
                } else {
                    return null;
                }
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    @Override
    public Stat setData(String path, byte[] data, int version)
            throws KeeperException, InterruptedException {
        int count = 0;
        do {
            try {
                return super.setData(path, data, version);
            } catch (KeeperException.ConnectionLossException e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
                Stat s = exists(path, false);
                if (s != null) {
                    if (getData(path, false, s) == data) {
                        return s;
                    }
                } else {
                    return null;
                }
            }
        } while (!closed && (limit == -1 || count++ < limit));
        return null;
    }

    /**
     * @param limit
     */
    public void setRetryLimit(int limit) {
        this.limit = limit;
    }

    /**
     * @return true if successfully connected to zookeeper
     */
    public boolean testConnection() {
        int count = 0;
        do {
            try {
                return super.exists("/", null) != null;
            } catch (Exception e) {
                LoggerFactory.getLogger().warn(
                        "ZooKeeper connection lost.  Trying to reconnect.");
            }
        } while (count++ < 3);
        return false;
    }

}

对于的测试类ZooKeeperRobotTest。


import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.List;


/**
 * @author elite_jigang@163.com
 */
public class ZooKeeperRobotTest {

    private final static String ZOO_KEEPER_ADDRESS = "192.168.115.15:2222,192.168.115.2:2222,192.168.115.20:2222";
    private boolean connected = true;

    private ZooKeeper zooKeeper;

    @Test
    public void testCreatePersistent() throws IOException, KeeperException, InterruptedException {
        zooKeeper= new ZooKeeperRobot(ZOO_KEEPER_ADDRESS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    connected = false;
                }
            }
        });
        ((ZooKeeperRobot)zooKeeper).setRetryLimit(3);
        System.out.println("connect to ZooKeeper servers : " + ((ZooKeeperRobot) zooKeeper).testConnection());
        String data = "HBase, SolrCloud,Kafka";
        String nodePath1  = "/root2/node_b";

        String[] partsPath = nodePath1.split("/");
        int checkSize = partsPath.length - 1;
        for(int i = 0; i< checkSize; i++){
            String prefixMark = "";
            for(int j = 0; j <= i; j++){
                prefixMark += partsPath[j] + "/";
            }
            if(prefixMark.length() != 1){
                prefixMark = prefixMark.substring(0, prefixMark.length()-1);
                Stat stat = ((ZooKeeperRobot)zooKeeper).exists(prefixMark, false);
                if(stat == null){
                    ((ZooKeeperRobot)zooKeeper).create(prefixMark, "12333333".getBytes(),
                            ZooDefs.Ids.OPEN_ACL_UNSAFE,
                            CreateMode.PERSISTENT);
                }
            }
        }
        Stat stat = ((ZooKeeperRobot)zooKeeper).exists(nodePath1, null);
        if(stat == null){
            String result1 = ((ZooKeeperRobot)zooKeeper).createPersistent(nodePath1,
                    data.getBytes(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE,
                    CreateMode.PERSISTENT);
            System.out.println("-------" + result1);
            Assert.assertEquals(result1, nodePath1);
        }
        System.out.println("-------");

        ((ZooKeeperRobot)zooKeeper).close();
    }
    @org.testng.annotations.Test
    public void testCreatePersistentNode1() throws Exception {
        ZooKeeper zooKeeper= new ZooKeeperRobot(
                                      ZOO_KEEPER_ADDRESS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    connected = false;
                }
            }
        });
        ((ZooKeeperRobot)zooKeeper).setRetryLimit(3);
        System.out.println("connect to ZooKeeper servers : " + ((ZooKeeperRobot) zooKeeper).testConnection());
        String data = "HBase, SolrCloud,Kafka";
        String nodePath1  = "/root/node_b";
        String firstPath2 = "/root";
        String result1 = ((ZooKeeperRobot)zooKeeper).create(firstPath2,
                "123".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT);
        System.out.println("-------" + result1);
        Assert.assertEquals(result1, firstPath2);

        Stat stat = ((ZooKeeperRobot)zooKeeper).exists(nodePath1, null);
        if(stat == null){
            result1 = ((ZooKeeperRobot)zooKeeper).create(firstPath2,
                    data.getBytes(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE,
                    CreateMode.PERSISTENT);
            System.out.println("-------" + result1);
            Assert.assertEquals(result1, nodePath1);
        }
        System.out.println("-------");

        ((ZooKeeperRobot)zooKeeper).close();
    }

    @org.testng.annotations.Test
    public void testDelete() throws Exception {

        zooKeeper= new ZooKeeperRobot(ZOO_KEEPER_ADDRESS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    connected = false;
                }
            }
        });
        ((ZooKeeperRobot)zooKeeper).setRetryLimit(3);
        System.out.println("connect to ZooKeeper servers : " + ((ZooKeeperRobot) zooKeeper).testConnection());
        String nodePath1  = "/root/node_b";
        String nodePath2  = "/root2/node_b";
        String nodePath3  = "/root";
        String nodePath4  = "/root2";

        ((ZooKeeperRobot)zooKeeper).delete(nodePath1, -1);
        ((ZooKeeperRobot)zooKeeper).delete(nodePath2, -1);
        ((ZooKeeperRobot)zooKeeper).delete(nodePath3, -1);
        ((ZooKeeperRobot)zooKeeper).delete(nodePath4, -1);
    }


    @org.testng.annotations.Test
    public void testGetACL() throws Exception {
        zooKeeper= new ZooKeeperRobot(ZOO_KEEPER_ADDRESS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    connected = false;
                }
            }
        });
        ((ZooKeeperRobot)zooKeeper).setRetryLimit(3);
        System.out.println("connect to ZooKeeper servers : " + ((ZooKeeperRobot) zooKeeper).testConnection());
        String nodePath1  = "/root1/node_b";

        List<ACL> list = ((ZooKeeperRobot)zooKeeper).getACL(nodePath1, new Stat());
        for(ACL acl: list){
            System.out.println(" acl:"+ acl);
        }
    }

    @org.testng.annotations.Test
    public void testGetChildren() throws Exception {
        ZooKeeper zooKeeper = null;
        try {
            zooKeeper =
                    new ZooKeeperRobot(ZOO_KEEPER_ADDRESS,
                            3000,  // millisecond
                            new Watcher() {

                                @Override
                                public void process(WatchedEvent event) {
                                    if (event.getState() == Event.KeeperState.Expired) {
                                        connected = false;
                                    }
                                }
                            });
            ((ZooKeeperRobot) zooKeeper).setRetryLimit(3);
            connected  = ((ZooKeeperRobot)zooKeeper).testConnection();
            System.out.println(" connect to zookeeper : "+ connected);

            Stat stat = new Stat();
            String path = "/test";
            try {
                List<String> childs = zooKeeper.getChildren(path, false, stat);
                for(String node: childs){
                    System.out.println("\t"+ node);
                }
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @org.testng.annotations.Test
    public void testGetData() throws Exception {
        zooKeeper= new ZooKeeperRobot(ZOO_KEEPER_ADDRESS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    connected = false;
                }
            }
        });
        ((ZooKeeperRobot)zooKeeper).setRetryLimit(3);
        System.out.println("connect to ZooKeeper servers : " + ((ZooKeeperRobot) zooKeeper).testConnection());
        String nodePath1  = "/root1/node_b";

        System.out.println("----"+ new String(((ZooKeeperRobot) zooKeeper).getData(nodePath1, false, new Stat())));
    }


    @org.testng.annotations.Test
    public void testSetACL() throws Exception {

    }

    @org.testng.annotations.Test
    public void testSetData() throws Exception {
        zooKeeper= new ZooKeeperRobot(ZOO_KEEPER_ADDRESS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.Expired) {
                    connected = false;
                }
            }
        });
        ((ZooKeeperRobot)zooKeeper).setRetryLimit(3);
        System.out.println("connect to ZooKeeper servers : " + ((ZooKeeperRobot) zooKeeper).testConnection());
        String nodePath1  = "/root1/node_b";

        System.out.println("----"+ ((ZooKeeperRobot) zooKeeper).setData(nodePath1, "2222222".getBytes(), -1));
        System.out.println("*****" + new String(((ZooKeeperRobot) zooKeeper).getData(nodePath1, false, new Stat())));
    }

}

欢迎关注我的微信公众号
weixing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值