zoukankan      html  css  js  c++  java
  • Zookeeper-基本概念

      ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。它是一个典型的分布式数据一致性的解决方案,分布式应用可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。

    角色:

      1、Leader(领导者):负责进行投票的发起和决议,更新系统状态

      2、Learner(学习者):包含Follower(跟随者)和Observer(观察者)

        Follower:接收客户端请求并向客户端返回结果,在选主过程中参与投票

        Observer:接收客户端连接,将写请求转发给Leader节点。但Observer不参与投票,只同步leader的状态。其目的是为了扩展系统,提高读取速度

      3、Client(客户端):请求发起方

    会话(SESSION):

      session指客户端会话,在zookeeper中,一个客户端连接指客户端与服务端之间的一个TCP长连接。对外默认服务端口2181。客户端启动时,与服务器建立一个TCP连接,从第一次连接建立开始,客户端会话的生命周期就开始了。客户端可通过心跳检测与服务器保持有效会话,也能够想Zookeeper服务器发送请求并接收响应,同时能接收来自服务器的Watch事件通知。当异常导致客户端连接断开时,只要在sessionTimeout规定时间内重连上集群中任意一台服务器,那么之前创建的会话依然有效。

    数据节点(Znode):

      zookeeper中,节点分为两类。第一类是构成集群的集群,称之为机器节点。第二类是数据模型中的数据单元,称之为数据节点(Znode)。zookeeper将所有数据存储在内存中,数据模型是一颗树(Znode Tree)。由斜杠(/)分割的路径,就是一个Znode。每个Znode都会保存自己的数据内容,同时保存一系列属性信息。

    版本:

      对应每个Znode,zookeeper都会为其维护一个叫做stat的数据结构,stat中记录了这个Znode的三个数据版本,分别是version(当前版本),cversion(当前Znode子节点的版本)和aversion(当前Znode的ACL版本)。

    Watcher:

      事件监听器,zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发时,Zookeeper服务端会将事件通知到感兴趣的客户端上去。

    ACL:

      zookeeper采用ACL(Access Control Lists)策略来进行权限控制。其定义了五种权限。

      CREATE:创建子节点的权限。

      READ:获取节点数据和子节点列表的权限。

      WRITE:更新节点数据的权限。

      DELETE:删除子节点的权限。

      ADMIN:设置节点ACL的权限。

    系统模型:

      

    Zookeeper可以保证如下分布式一致性特性:

      顺序一致性:从同一个客户端发起的事务请求,最终会严格地按照发起顺序被应用到Zookeeper中去。

      原子性:所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的。要么所有机器都成功应用某一事务,要么都没应用。

      单一视图:客户端不论连接到哪个服务器,看到的服务端数据模型都是一致的。

      可靠性:一旦服务端成功应用一个事务,并完成对客户端的响应,那么该事务引起的服务端状态变更会被一直保留下来,除非有另一个事务对其进行变更。

      实时性:Zookeeper仅仅保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。

    Zookeeper四个设计目标:后期补充

      简单的数据模型:

      可以构建集群:Zookeeper集群的每台机器都会在内存中维护当前服务器状态,并且机器之间都互相保持通信。只要集群中超过一半的机器能够正常工作,那么集群就能正常对外服务。

      顺序访问:对于来自客户端的每个更新请求,zookeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序。

      高性能:Zookeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,因此它尤其适用于以读操作为主的应用场景。

    ZAB协议:

      支持崩溃恢复的原子广播协议。Zookeeper使用一个单一的主进程来接收并处理客户端所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以事务Proposal的形式广播到所有的副本进程。ZAB协议的主备模型架构保证同一时刻集群中只能够有一个主进程来广播服务器的状态变更,因此能很好的处理客户端大量的并发请求。

    ZAB协议核心:

      定义了对于会改变Zookeeper服务器数据状态的事务请求的处理方式,即:

      所有事务请求必须由一个全局唯一的服务器来协调处理,即Leader服务器,余下的为Follower服务器。Leader负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有Follower。之后Leader等待所有Follower反馈,一旦超过半数的Follower进行正确反馈,那么Leader会再次向所有的Follower分发Commit消息,要求其将前一个Proposql进行提交。

    工作原理:

      Zookeeper的核心是原子广播,该机制保证了各个Server之间的同步。通过Zab协议实现这个机制。

      Zab协议有两种模式,分别是崩溃恢复(选主)模式和消息广播(同步)模式。当服务启动或在Ledaer崩溃后,Zab进入恢复模式,当领导者被选举出来,且半数Server完成了和Leader的状态同步后,恢复模式结束。状态同步保证了Leader和Server具有相同的系统状态。当集群中过半的Follower完成了和Leader的状态同步,就会进入消息广播模式。当一台同样遵守ZAB协议的新服务器启动后加入集群,如果此时集群中已经存在Leader进行消息广播,那么新服务器会自觉进入数据恢复模式,找到Leader,并与其进行数据同步,然后一起参与到消息广播中去。

      为了保证事物的顺序一致性,zookeeper采用全单调递增的唯一id号(zxid,事务id)来标识事务。所有提议(proposal)都在被提出的时候加上了zxid。每一个事务Proposal安装其zxid的先后顺序来进行排序与处理,以此保证每一个消息严格的因果关系。

      消息广播:针对客户端的事务请求,Leader会为其生成对应的事务Proposql,并将其发送给集群中其余所有机器,然后再收集各自的选票,最后进行事务提交。

      ZAB协议规定如果一个事务Proposql在一台机器上被处理成功,那么应该在所有的机器上都被处理成功。哪怕机器出现故障崩溃。但在崩溃恢复过程中,可能会出现两个数据不一致性的隐患。

      1、Leader提交一个事务,并得到过半Follower的ACK反馈,但在它将Commit发出后,Leader挂了。此时ZAB要保证事务最终能在所有服务器上都被提交成功,否则出现不一致。

      2、如果在崩溃恢复过程中出现一个需要被丢到的提案,那么崩溃恢复结束后,需要跳过该事务。

      针对上述两种情况,ZAB协议必须设计这样一个Leader选举算法:能够确保提交已经被Leader提交的事务,同时丢弃已经被跳过的事务。

      如果让Leader选举算法能够保证新选举出来的Leader拥有集群中所有机器最高编号(即ZXID)的事务,那么就可以保证这个新选举出来的Leader一定具有所有已提交的提案,并可以省去Leader检测Proposql的提交和丢弃工作的这步操作。

      ZAB协议如果处理需要被丢弃的事务Proposal:

        在设计事务编号ZXID中,ZXID是一个64位的数字,其中低32位可以看作是一个简单单调递增的计数器。针对客户端的每一个事务请求,Leader在产生一个新Proposql时,会对计数器进行+1操作。高32位代表Leader周期epoch的编号。每当新的Leader产生,就会从这个Leader中取出其本地日志上最大事务的ZXID,并从该ZXID中解析出对应的epoch,并对其进行+1操作,之后以此编号作为新的epoch,并将低32位置0来开始生成新的ZXID。这样来区分Leader周期变化,能有效避免不同的Leader错误地使用相同的ZXID编号提出不一样的事务的异常情况。

        基于这一策略,当一个包含了上一个Leader周期中尚未提交过的事务的服务器启动时,其肯定无法成为Leader。因为当前集群中一定包含一个Quorum集合,该集合中的机器一定包含了最高epoch的事务,因此该服务器的事务肯定不是最高。也无法成为Leader。当这台机器加入集群中,以Follower角色连接上Leader,Leader会根据自身最后被提交的事务来和Follower的事务进行比对,Leader会要求Follower进行一个回退操作,回退到一个确实已经被集群中过半机器提交的最新事务。

  • 相关阅读:
    C#时间格式转换问题(12小时制和24小时制)
    ajax跨域请求webservice webconfig配置
    C#时间戳转化为DateTime
    C#生成缩略图
    codeforces-1348-C Phoenix and Distribution
    P4314 CPU监控
    YangK's dfs序与树链剖分
    Yangk's 静态主席树
    P2253 好一个一中腰鼓!
    codeforces-1341D-Nastya and Scoreboard 记忆化搜索
  • 原文地址:https://www.cnblogs.com/zhangbLearn/p/9577369.html
Copyright © 2011-2022 走看看