zoukankan      html  css  js  c++  java
  • ZooKeeper 笔记

    1、分布式系统常见问题

    部分失败:发生网络错误时候,发送者不知道接受者是否已经收到信息,接收者可能收到、可能没有、可能进程已死。发送者需要重新连接接收者,再次发送以确认。


    2、ZooKeeper 用于正确处理部分失败‘,其特点是

    (1)、ZooKeeper 核心是一个精简的文件系统,提供排序、通知等操作。

    (2)、 富有表现力,可实现分布式队列、分布式锁、领导者选举等数据结构和协议。

    (3)、具有高可用性,只要集群一半以上机器可以,则整体可能,可帮助系统避免出现单点故障。

    (4)、采用松耦合方式,参与者不需要彼此了解,消息是异步的。

    (5)、是一个资源库,提供了一个通用协调模式实现和方法的开源共享存储库。


    3、ZooKeeper 的连接

    当一个ZooKeeper 实例创建时候,会启动一个线程连接到ZooKeeper服务,由于对构造函数的调用是立即返回的,所以在使用新建ZooKeeper对象之前,一定要等到其与ZooKeeper服务之间的连接建立成功。可以使用以下两种方法。

    (1)、使用CountDownLatch

    public class ConnectionWatcher implements Watcher {
    
        protected static final int SESSION_TIMEOUT = 5000;
    
        protected ZooKeeper zk;
        protected CountDownLatch connectedSignal = new CountDownLatch(1);
    
        public void connect(String clusters) throws IOException, InterruptedException {
            this.zk = new ZooKeeper(clusters, SESSION_TIMEOUT, this);
            this.connectedSignal.await();
        }
    
        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == KeeperState.SyncConnected) {
                this.connectedSignal.countDown();
            }
        }
    
        public void close() throws InterruptedException {
            if (this.zk != null) {
                this.zk.close();
            }
        }
    
    }


    (2). 使用 volatile 变量

    public class ConnectionWatcher implements Watcher {
    
        protected static final int SESSION_TIMEOUT = 5000;
    
        protected ZooKeeper zk;
        private volatile boolean isConnectd = false;
    
        public void connect(String clusters) throws IOException {
            this.zk = new ZooKeeper(clusters, SESSION_TIMEOUT, this);
           while(!this.isConnectd)
           {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {  }
           }
        }
    
        @Override
        public void process(WatchedEvent event) {
            if (event.getState() == KeeperState.SyncConnected) {
                this.isConnectd=true;
            }
        }
    
        public void close() throws InterruptedException {
            if (this.zk != null) {
                this.zk.close();
            }
        }
    
    }

    4、ZooKeeper数据模型

    znode 能存储的数据限制在 1MB 以内

    ZooKeeper 的数据访问有原子性:读写znode要么全部成功,要么全部失败,不会部分读写。

    znode类型:PERSISTENT、EPHEMERAL、PERSISTENT_SEQUENTIAL、EPHEMERAL_SEQUENTIAL

    ZooKeeper 的 Watcher : 在读操作exists, getDate, getChildren  时候可以设置观察,有NodeCreatedNodeDataChangedNodeDeletedNodeChildrenChanged事件。

    znode 的 ACL:可以通过用户名密码、客户机主机名、客户端IP 等进行身份认证。

    znode的删除:不能递归,必须先删子节点,再删父节点


    5、Zab 协议

    ZooKeeper 确保对znode树的每一个修改都会被复制到集合体中超过半数的机器上。如果少于半数的机器出现故障,则最少有一台机器会保存最新的状态,其余副本最终也会更新到这个状态。

    Zab 协议阶段:

    (1). 所有机器选出一台leader,其余作为follower,一旦半数follower 与leader 同步,则表明这个阶段已经完成。

    (2). 所有写请求先写给leader,再由leader广播给follower,在半数follower 持久化修改后,leader 才持久化,然后客户端才收到响应。故而协议具有原子性。

    (3). 若leader死掉,则其余follower选出另外一个leader,原先的leader在重启后作为follower。


    6、ZooKeeper 的数据一致性

    (1). 顺序一致性:若客户端将znode 值设先设为a, 再设为b, 则没有客户端可能再先看到b之后再看到a

    (2). 原子性:要么全部成功要么全部失败,不会部分更新

    (3). 单系统映像:无论客户端连接到哪台服务器,其与系统看见的视图是一样的。

    (4). 容错性:一旦更新成功,其结果将持久存在,不被撤销

    (5). 及时性:任何客户端所看到系统视图的滞后都是有限的,不会超过几十秒。


    7、会话

    客户端的会话空闲超过一定时间,可以通过客户端发送心跳保持会话不过期(心跳由ZooKeeper客户端自动发送,不要用户代码维护)。

    客户端可以自动进行故障切换,切换到另外一台服务器。

    TickTime 一般为2秒,会话超时可以设置在 2个 TickTime 到 20 个 TickTime 之间。

    ZooKeeper 集合体中的服务器越多,会话超时应该设置越大,可以对应用程序进行设计,在超时之前重启。

    将会话ID 和 密码保存在数据库中,可以将应用程序关闭,然后在重启之前凭借所保存的会话ID 和 密码 来回复会话环境。


    8. 状态

    ZooKeeper.States:CONNECTING, ASSOCIATING, CONNECTED, CLOSED, AUTH_FAILED;

    Watcher.KeeperState:  Disconnected, SyncConnected, AuthFailed, Expired, 


    9. 异常恢复

    InterruptedException  并不意味着故障,而是意味着操作已经取消,不需要恢复。

    KeeperException.ConnectionLossException  此异常可恢复,一般需要重试操作

    KeeperException.SessionExpiredException  此异常不可恢复,需要重新连接


    以下异常按照具体的业务逻辑处理:

    KeeperException.NoNodeException 

    KeeperException.NodeExistException 

    KeeperException.BadVersionException 

    KeeperException.NoChildrebForEphemeralsException 

    KeeperException.NoNodeException 


    10.分布式锁服务

    有两个客户端差不多同时创建znode,分别为/leader/lock-1,  /leader/lock-2 , 那么创建/leader/lock-1 的客户端将持有锁,行使Super权限。

    如果leader 进程死亡,则/leader/lock-1 被删除, 此时创建 /leader/lock-2 的客户端将观察到 Watcher 事件,持有锁,行使Super权限。


    11、生产环境中注意环节

    (1)  ZooKeeper 应该运行在专用机器上,如果有其他程序竞争资源,将导致ZooKeeper性能明显下降。

    (2)  将 dataDir 和 dataLogDir 保存在不同的磁盘下。所有写操作都由leader完成。

    (3)  参数含义:

    tickTime = 2000                // 单位毫秒,其实是2秒

    clientPort = 2181

    dataDir =/disk1/zookeeper

    dataLogDir=/disk2/zookeeper

    initLimit=5                         //  所有follower 与 leader 连接、同步的时间。如果在initLimit内,半数follower未完成同步,则leader 放弃领导地位,进行另一次leader 选举。

    syncLimit=2                       // 某个follower 与 leader 连接、同步的时间。如果在syncLimit内,该follower未完成同步,则该follower 自己重启。


  • 相关阅读:
    PHP的常用框架有哪些?
    Django中反向生成models
    Django中使用django_debug_toolbar
    Django日志系统
    RESTful接口规范
    Django restframework
    Mysql数据备份与还原
    CORS解决跨域问题
    Linux下Python2升级Python3
    Django+Uwsgi+Nginx部署
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276322.html
Copyright © 2011-2022 走看看