ZooKeeper的基本概念

  • Architecture(架构)
  • Hierarchical namespace(层次命名空间)
  • Session(会话)
  • Watches(监视)

1、架构

服务怎么获取注册到zookeeper的权限_客户端

客户端:用于访问服务器获取服务,每个客户端定期向服务器发送消息以使服务器知道客户端是活跃的。当客户端连接时,服务器发送确认码。如果连接的服务器没有响应,客户端会自动将消息重定向到另一个服务器。

服务器:集群中的一个节点,为客户端提供服务。

服务器组:Ensemble,标识Zookeeper的一个服务器组织,最小服务器数量为3台。

首领:Leader,就像总统是通过选举的办法产生一样,Leader服务器节点控制其他节点或者是分配任务。一般读任务都不归他管,写操作会由它决策。负责响应所有对ZooKeeper状态变更的请求。

下属:Follower,就像领导的下属一样,从服务器的职责就是遵守Leader的指令。除了响应本服务器上的读请求外,follower还要处理leader的提议,并在leader提交该提议时在本地也进行提交。

观察者:Observer,如果ZooKeeper集群的读取负载很高,可以设置一些observer服务器,以提高读取的吞吐量。与Follower类似,但是不会持久化,不参与选举,不响应提议,也不计入服务器成员数中。

2、层次命名空间


右图是ZooKeeper的分层名字空间的示意图


  • 类似开发java工程下的包结构
  • 每个节点都叫znode
  • 以 分割各元素的路径
  • 顶层节点是 /
  • 有两个逻辑命名空间 config 和 workers 



服务怎么获取注册到zookeeper的权限_服务器_02

下面详细说明一下节点的含义。以下部分内容出自:


node既可以有其他子znode,又可以存放数据(严格说是必须存放数据,真没有的话得给个“”),znode被用来存储Byte级或KB级的数据,如状态信息、配置信息、位置信息等,因此znode可存放数据量的最大值默认被设为1MB,请注意,该值不仅计算数据的Byte数,所有子节点的名字也要折算成Byte数计入,因此znode的子节点数也不是无限的。改大这个参数可以存储更多数据或包含更多子znode,但我非常不建议这样做,因为这与ZooKeeper的设计目的相悖,只有数据足够小,才能保证ZooKeeper的高读取性能。如果要存储大量数据,有的是其他解决方案。


    除了数据外,znode还管理了其他一些元数据, 存储在 stat对象( 一个stat仅提供一个znode的元数据。它由版本号,操作控制列表(ACL),时间戳和数据长度组成。 中:


  • 版本号:znode的数据每次更新时,该版本号递增。当客户端请求该znode时,数据和版本号会一起发回。另外,当znode重建时版本号会被重置,但很多时候这是巨坑的来源,比如:客户端执行了’set /test “testdata” 1’,即指定版本1写/test节点,之后该znode被删除重建,数据默认置为“”,版本号还是1,此时客户端请求时虽然该版本号仍然存在,但已经是错误的数据了。
  • ACL:即Access Control List,ACL基本上是访问znode的认证机制。它管理所有znode读取和写入操作。用来限定哪些账号可以操作该znode。ZooKeeper内置了4种ACL模式,第1种是any,即不鉴权;第2种是super,即不受任何ACL约束的管理员模式;第3种是digest,使用用户名和密码进行认证;第4种是SASL,通常使用Kerberos协议来认证,但Kerberos也是个大坑,并且对性能也有一定影响。
  • 时间戳:其实就是zxid,存储该znode创建或修改时的时间戳,用于缓存验证或协调更新等。Zxid 是唯一的,并且为每个事务保留时间,以便你可以轻松地确定从一个请求到另一个请求所经过的时间。
  • 数据长度:存储在znode中的数据总量是数据长度。你最多可以存储1MB的数据。

Znode的类型

  Znode被分为持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点。

  • 持久节点 默认情况下,除非另有说明,否则所有znode都是持久的。持久节点只能用delete来删除。
  • 临时节点 - 客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除,常用来检测会话的有效性。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。
  • 顺序节点 - 顺序节点可以是持久的或临时的。当一个新的znode被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置znode的路径。例如,如果将具有路径 /myapp 的znode创建为顺序节点,则ZooKeeper会将路径更改为 /myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个znode使用相同的数字。顺序节点在锁定和同步中起重要作用。

3、Sessions(会话)

会话对于ZooKeeper的操作非常重要。会话中的请求按FIFO顺序执行。一旦客户端连接到服务器,将建立会话并向客户端分配会话ID 。
客户端以特定的时间间隔发送心跳以保持会话有效。如果ZooKeeper集合在超过服务器开启时指定的期间(会话超时)都没有从客户端接收到心跳,则它会判定客户端死机。

会话超时通常以毫秒为单位。当会话由于任何原因结束时,在该会话期间创建的临时节点也会被删除。

会话的状态:

  • connecting:一旦客户端开始创建Zookeeper对象,那么客户端状态就会变成CONNECTING状态
  • connected:连接成功后,客户端状态变为CONNECTED
  • reconnecting :由于断网或其他原因,客户端与服务端之间会出现断开情况,Zookeeper客户端会自动进行重连服务
  • reconnected:直到重新连上服务端后,状态又变为CONNECTED
  • close:会话超时、权限检查或是客户端主动退出程序等情况,客户端的状态就会直接变更为CLOSE状态。

以下内容参考文章:

Session是Zookeeper中的会话实体,代表了一个客户端会话,其包含了如下四个属性

  1. sessionID。会话ID,唯一标识一个会话,每次客户端创建新的会话时,Zookeeper都会为其分配一个全局唯一的sessionID。


  2. TimeOut。会话超时时间,客户端在构造Zookeeper实例时,会配置sessionTimeout参数用于指定会话的超时时间,Zookeeper客户端向服务端发送这个超时时间后,服务端会根据自己的超时时间限制最终确定会话的超时时间。


  3. TickTime。下次会话超时时间点,为了便于Zookeeper对会话实行"分桶策略"管理,同时为了高效低耗地实现会话的超时检查与清理,Zookeeper会为每个会话标记一个下次会话超时时间点,其值大致等于当前时间加上TimeOut。


  4. isClosing。标记一个会话是否已经被关闭,当服务端检测到会话已经超时失效时,会将该会话的isClosing标记为"已关闭",这样就能确保不再处理来自该会话的心情求了。


会话管理机制是通过分桶策略来进行的的,以便对会话进行不同区块的管理和统一的处理。将会话分配到不同的桶依据是会话的超时时间。服务器循环向客户端发送ping以更新超时时间。


4、Watches(监视)

监视是一种简单的机制,使客户端收到关于ZooKeeper集合中的更改的通知。客户端可以在读取特定znode时设置Watches。Watches会向注册的客户端发送任何znode(客户端注册表)更改的通知。

Znode更改是与znode相关的数据的修改或znode的子项中的更改。只触发一次watches。如果客户端想要再次通知,则必须通过另一个读取操作来完成。当连接会话过期时,客户端将与服务器断开连接,相关的watches也将被删除。

以下的三个变革可以触发watch:

  • znode数据的改变,如使用setData操作在znode域中写入新数据。
  • znode子节点的改变,如使用delete操作删除znode的子节点。
  • znode的创建或删除。

关于watches和通知,Zookeeper确保维护一下几点:

  • Zookeeper保证所有的watch都是按先进先出(FIFO)排序,通知也是按顺序发送。
  • 同一个znode的第二次修改发生之前watch的通知就一定发送给客户端。
  • watch事件的顺序依赖于Zookeeper服务所能检测到的数据更新的顺序。