Zookeeper集群运行原理

客户端测试程序:

package cn.onea.common.zoo;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

public class ZCT {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        CountDownLatch latch=new CountDownLatch(1);
        ZooKeeper zooKeeper=new ZooKeeper("localhost:2181", 10000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                if(watchedEvent.getState() == Event.KeeperState.SyncConnected){
                    System.out.println("******************************success");
                    latch.countDown();
                }
                if(watchedEvent.getState() == Event.KeeperState.Disconnected){
                    System.out.println("Zookeeper连接已断开");
                }
            }
        });

        for(int i=0;i<1000;i++){
            long c = System.currentTimeMillis();
//            String s = zooKeeper.create("/CLU" + c, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//            System.out.println("################################zookeeper created "+s);
            Stat exists = zooKeeper.exists("/a", false);
            System.out.println("################################zookeeper exist "+exists);
            Thread.sleep(1000);
        }

        zooKeeper.close();
    }
}

 

配置四个节点的集群,一次启动A B C D四个节点后,假设C节点被选为Leader,其他节点为Follower:


Java客户端连接节点A,可以正常的读写操作。当B节点挂掉后,客户端还可以正常读写,因为存活的节点数量还有3个,超过了集群总节点数量的一半。当B和D两个节点挂掉以后,客户端连接异常,不可以使用集群功能,因为存活的节点数量只有2个,没有超过集群节点的总数量的一半。

 

配置三个节点的集群,一次启动A B C 三个节点后,假设C节点被选为Leader,其他节点为Follower:


Java客户端连接节点A,可以正常的读写操作。当B节点挂掉后,客户端还可以正常读写,因为存活节点的数量还有2个,超过了集群节点的一半。


配置四个节点的集群,一次启动A B C D四个节点后,假设C节点被选为Leader,其他节点为Follower:


Java客户端连接节点A,可以正常的读写操作。当C节点Leader节点挂掉后,客户端也会断开不能进行读写,当leader选举完后,客户端可以继续连接zookeeper进行读写,假设新Leader变为了D节点,这时候如果D挂掉,客户端又会断开连接不能进行读写,存活节点数少于集群的一半,不能在使用集群服务。

 

配置三个节点的集群,一次启动A B C 三个节点后,假设B节点被选为Leader,其他节点为Follower:


Java客户端连接节点C,可以正常读写,当B节点也就是Leader节点挂掉,客户端也会自动断开不能进行读写,当B挂掉后A C中会有一个节点会选作主节点,此时再次连接C节点可以正常读写,(当时有个疑问,只剩下2个节点了还能选举?其实不是2个节点,节点依旧是3个,这个数量是配置文件中zoo.cfg中配置决定的,所以还是3个,没问题)。

 

连接配置:

 

new ZooKeeper("ip:端口", 10000, watcher) 会使用这一个节点访问集群,如果这个节点挂掉就不能访问集群了,因为没有配置其他节点。

new ZooKeeper("ip:端口,ip:端口,ip:端口", 10000, watcher)  会随机选择一个节点访问集群。

 

总结:


集群节点的数量是由配置文件zoo.cfg中配置的server数量决定的,集群中有节点(Leader/Follower)挂掉后,如果剩余存活的节点数量超过集群总数量的一半,集群就可以正常提供服务。满足半数以上节点存活的前提下如果Leader挂掉,会进行leader选举,这时候客户端会被迫断开,不能使用集群服务,直到新leader选举出来才可以去连接使用集群服务;满足半数以上节点存活的前提下如果挂掉的是follower节点,不会断开连接依旧可以正常读写。

Zookeeper集群最少节点数量为3个,通常设置为奇数个,集群半数以上存活要求,2N+1 和 2N+2个节点最多允许N个节点出错,设置为奇数个数量可以节约服务器资源。

 

你可能感兴趣的:(zookeeper)