Zookeeper中组成员的关系
您目前处于:技术核心竞争力  2014-07-23

h理解Zookeeper的一种方法就是将其看做一个具有高可用性的文件系统。但这个文件系统中没有文件和目录,而是统一使用"节点(node)的概念,成为znode。znode既可以作为作为保存数据的容器,也可以作为保存其他znode的容器。所有的znode构成一个层次化的命名空间。

创建组

改程序在Zookeeper中新建表示组的znode

public class CreatedGroup implemetns Watcher {
    private static final int SESSION_TIMEOUT = 5000;
    
    private Zookeeper zk;
    private CountDownLatch connectedSignal = new CountDownLatch(1);

    public void connect(String hosts) throws IOException, InterruptedException {
        zk = new Zookeeper(hosts, SESSION_TIMEOUT, this);
        connectedSignal.await();
    }

    @Override
    public void process(WatchedEvent event) { // Watcher interface
        if(event.getState() == KeeperState.SyncConnected) {
            connectedSignal.countDown();
        }
    }

    public void create(String groupName) 
    throws KeeperException, InterruptedException {
        String path = "/" + groupName;
        String createdPath = zk.create(path, null/*data*/, 
                                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        Systemout.println("Creted " + createdPath);
    }

    public void close() throws InterruptedException {
        zk.close();
    }
}

Watch对象接收来自于Zookeeper的回调,以获得各种事件的通知。

Watcher类的接口只有一个方法:

public void process(WatchedEvent event);

客户端已经与Zookeeper建立连接后,Watcher的process()方法会被调用,参数是一个表示该连接的时间。

有两种类型的znode:短暂的和持久的。创建znode的客户端断开连接时,无论客户端是明确断开还是因为任何原因而终止,短暂znode都会被Zookeeper服务删除。与之相反,当客户端断开连接时,持久znode不会被删除。

加入组

用于将成员加入组:

public class JoinGroup extends ConnectionWatcher {
    public void join(String groupName, String memberName) 
    throws KeeperException, InterrupedException {
        String path = "/" + groupName + "/" + memberName);
        String createdPath = zk.create(path, null/*data*/, 
                                    Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("created " + createdPath);
    }
}

用于等待建立于Zookeeper链接的辅助类

public class ConnectionWatcher implements Watcher {
    public static final int SESSION_TIMEOUT = 5000;

    protected Zookeeper zk;
    private CountDownLatch connectedSignal = new CountDownLatch(1);

    public void connect(String hosts) throws IOException, INterruptedException {
        zk = new Zookeeper(hosts, SESSION_TIMEOUT, this);
        connectedSignal.await();
    }

    @Override
    public void process(WatchedEvent event) {
        if(event.getState() == KeeperState.SyncConnected) {
            connectedSignal.countDown();
        }
    }
}

列出组成员

public class Listroup extends ConnectionWatcher {
    public void list(String groupName) 
    throws KeeperException, InterruptedException {
        String path = "/" + groupName;

        try {
            List<String> children = zk.getChildren(path, false);
            if(children.isEmpty()) {
                System.out.println("No memebers in group" + groupName);
                return;
            }
            for(String child : children) {
                System.out.println(child);
            }
        } catch(KeeperExcepion.NoNodeException e) {
            System.out.println("Group " + groupName + " does not exist");
            return;
        }
    }
}

如果一个znode上设置了观察标识,那么一旦该znode的状态改变,关联的观察(Watcher)会被触发。

删除组

Zookeeper提供了一个delete()方法,该方法有两个参数:路径和版本号。如果所提供的版本号与znode的版本号一致,Zookeeper会删除这个znode,这是一种乐观的加锁机制,使客户端能够检测出对znode的修改冲突。通过将版本号设置为-1,可以绕过这个版本检测机制,不管znode的版本号是什么而直接将其删除。

public class DeleteGroup extends ConnectionWatcher {
    
    public void delete(String groupName) 
    throws KeeperException, InterruptedException {
        String path = "/" + groupName;

        try {
            List<String> children = zk.getChildren(path, false);
            for(String child : children) {
                zk.delete(path + "/" + child, -1);
            }
            zk.delete(path, -1);
        } catch(KeeperException.NoNodeException e) {
            System.out.println("Group " + groupName + " does not exist");
        }
    }
}

转载请并标注: “本文转载自 linkedkeeper.com ”  ©著作权归作者所有