Java Web分布式篇之ZooKeeper

Java Web系列文章汇总贴: Java Web知识总结汇总


分布式系统的经典理论

CAP

  • C (Consistency 一致性):对某个指定的客户端来说,读操作能返回最新的写操作。
    对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
  • A (Availability 可用性):非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。
    合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回 50,而不是返回 40。
  • P (Partition Tolerance 分区容错性):当出现网络分区后,系统能够继续工作。打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。

熟悉 CAP 的人都知道,三者不能共有,如果感兴趣可以搜索 CAP 的证明,在分布式系统中,网络无法 100% 可靠,分区其实是一个必然现象。

BASE

BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。

  • 基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。
  • 软状态:允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是 CAP 中的不一致。
  • 最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。

BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。
BASE 和 ACID 是相反的,它完全不同于 ACID 的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。

参考:
Zookeeper系列(1)–分布式一致性理论,CAP,BASE理论


ZK简介

ZooKeeper是一个开放源代码的、高效、可靠的分布式协调服务。设计目标是:将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

ZooKeeper的设计目标:

  • 简单的数据模型
  • 可以构建集群
  • 顺序访问
  • 高性能

ZK原理

拜占庭将军问题(Byzantine Generals Problem)

Leslie Lamport在1982年提出的虚拟模型,用来解释一致性问题。拜占庭作为东罗马帝国的首都,地域辽阔,在首都周边有众多将军负责城防,将军之间通过信使来传递消息,达成某些一致的决定。但由于将军中存在叛徒,叛徒会想尽一切办法干扰一致性的达成,甚至是达成叛徒想要的共识从而实现攻击。
拜占庭问题,假设节点总数是N,叛徒将军数为F,则当 N 》= 3F+1 时,问题才有解,共识才能达成,这就是Byzantine Fault Tolerant(BFT)算法。
基于以上分布式理论,对一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间反复权衡,于是产生了一系列的一致性协议,如2PC&3PC中涉及的一致性协议,Paxos一致性理论。

更多:
Zookeeper系列(2)–2PC、3PC及其应用
Zookeeper系列(3)–Paxos算法的原理及过程透彻理解

ZoopKeeper采用的一致性协议–ZAB(ZooKeeper Atomic Broadcast,原子消息广播协议)协议

ZAB协议

ZAB协议的核心定义了对于那些改变ZooKeeper服务器数据状态的事务请求的处理方式,即:
所有事务请求必须有一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,而余下的其他服务器则成为Follower服务器。Leader服务器负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进行提交。
另,ZooKeeper中还有一种机器角色:Observer。Observer机器不参与Leader选举过程,也不参与写操作的“过半写成功”策略,因此Observer可以在不影响写性能的情况下提升集群的读性能。
Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主-Leader选举)和广播模式(数据同步)。

Leader选举过程(FastLeaderElection算法)

Leader选举是保证分布式数据一致性的关键所在。当Zookeeper集群中的一台服务器出现以下两种情况之一时,需要进入Leader选举。

服务器启动时期的Leader选举

若进行Leader选举,则至少需要两台机器,这里选取3台机器组成的服务器集群为例。在集群初始化阶段,当有一台服务器Server1启动时,其单独无法进行和完成Leader选举,当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程。选举过程如下

  • (1) 每个Server发出一个投票。由于是初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0),Server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。
  • (2) 接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
  • (3) 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下
    A)优先检查ZXID。ZXID比较大的服务器优先作为Leader。
    B)如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。
    对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0),首先会比较两者的ZXID,均为0,再比较myid,此时Server2的myid最大,于是更新自己的投票为(2, 0),然后重新投票,对于Server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。
  • (4) 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于Server1、Server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了Leader。
  • (5) 改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。

服务器运行时期的Leader选举

在Zookeeper运行期间,Leader与非Leader服务器各司其职,即便当有非Leader服务器宕机或新加入,此时也不会影响Leader,但是一旦Leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮Leader选举,其过程和启动时期的Leader选举过程基本一致。假设正在运行的有Server1、Server2、Server3三台服务器,当前Leader是Server2,若某一时刻Leader挂了,此时便开始Leader选举。选举过程如下

  • (1)变更状态。Leader挂后,余下的非Observer服务器都会讲自己的服务器状态变更为LOOKING,然后开始进入Leader选举过程。
  • (2)每个Server会发出一个投票。在运行期间,每个服务器上的ZXID可能不同,此时假定Server1的ZXID为123,Server3的ZXID为122;在第一轮投票中,Server1和Server3都会投自己,产生投票(1, 123),(3, 122),然后各自将投票发送给集群中所有机器。
  • (3)接收来自各个服务器的投票。与启动时过程相同。
  • (4)处理投票。与启动时过程相同,此时,Server1将会成为Leader。
  • (5)统计投票。与启动时过程相同。
  • (6)改变服务器的状态。与启动时过程相同。

上边选出的只是准leader,要想变成leader还需完成数据同步。
更加详细的解释可参考《从Paxos到Zookeeper分布式一致性原理与实践》这本书。

数据同步

同步阶段主要是利用 leader 前一阶段获得的最新提议历史,同步集群中所有的副本。只有当 集群过半机器都同步完成,准 leader 才会成为真正的 leader。follower 只会接收 zxid 比自己的 last Zxid 大的提议。
当完成Leader选举后,进行故障恢复的第二步就是数据同步: Leader服务器会为每一个Follower服务器准备一个队列,并将那些没有被各个Follower服务器同步的事务以Proposal的形式逐条发给各个Follower服务器,并在每一个Proposal后都紧跟一个commit消息,表示该事务已经被提交,档follower服务器将所有尚未同步的事务proposal都从leader服务器同步过来并成功应用到本地后,leader服务器就会将该follower加入到真正可用的follower列表中。(新选举周期,epoch已经更新了)
每个zookeeper 事务都有一个全局唯一的事务ID,ZXID。ZXID 高32 位是leader 周期epoch,低32 位是递增计数器。从算法角度上看:

第一阶段(准leader生成初始事务集合)

所有follower 向准leader 发送自己最后接收的事务的epoch;
准leader 选取最大的epoch,加1得到e1,将e1 发送给follower;(准leader已经是zxid最大的机器了,且已经完成epoch更新了,防止说个leader出现)
follower 收到准leader 发送的epoch 值之后,与自己的epoch 值作比较,若小于,则将自己的epoch 更新为e1,并向准leader 发送反馈ACK信息(epoch 信息、历史事务集合);
准leader 接收到ACK 消息之后,会在所有历史事务集合中选择其中一个历史事务集合作为初始化事务集合,该事务集合满足ZXID最大;

第二阶段(正式同步)

准leader 将epoch 与 初始化事务集合发送给集群中过半的follower;每个follower 会分配到一个队列,leader 会将那些没有被各个follower 同步的事务以proposal 形式发送给各个follower,并在后面追加commit 消息,表示事务已被提交;follower 接收后,会执行初始化事务集合中的事务(执行过跳过,未执行执行),反馈给leader 表明自己已经处理(追上来了)leader 收到后过半反馈后,发送commit 消息;follower 接收到commit 消息后,提交事务;注意:在zk选举中,通过投票已经确认leader服务器是最大的zxid的节点了,所以同步过程没有那么复杂。

ZAB协议与Paxos算法的异同

ZAB协议并不是 Paxos 算法的一个典型实现,在讲解 ZAB和 Paxos之间的区别之前, 我们首先看下两者的联系,

  • 两者都有一个类似于Leader进程的角色,由其负责协调多个Follower运行
  • Leader进程都会等待超过半数的Follower做出正确的反馈后,才会将一个提案进行提交。
  • 在ZAB协议中,每个Proposal都包含了一个epoch值,用来代表当前的Leader 周期,在Paxos算法中,同样存在这样的一个标识,只是名字变成了Ballot。
  • 在Paxos算法中,一个新选举产生的主进程会进行两个阶段的工作,第一阶段被称为读阶段,在这个阶段中,这个新的主进程会通过和所有其他进程进行通信的方式来收集上一个—个主进程提出的提案,并将它们提交.第二阶段被称为写阶段,在这个阶段,与前主进程开始提出自己的提案。
  • 在Paxos算法设计的基础上, ZAB协议额外添加了一 个同步阶段。在同步阶段之前,ZAB协议也存在一个和Paxos算法中的读阶段I类似的过程,被称为发现( Discovery)阶段,在同步阶段中,新的 Leader会确存在过半数的Follower已经提交了之前Leader周期中的所有事物的Proposal,在这一同步阶段的引人,能够有效地保证Leader在新的周期中提出事务Proposal之前,所有的进程都已经完成了对之前所有事物的Proposal的提交。
  • 一旦完成同步阶段后,那么 ZAB就会执行和 Paxos算法类似 的写阶段。

总的来汫, ZAB协议和 Paxos本质区别在于,两者的设计目标不太一样。 ZAB 协议主要用于构建一个高可用的分布式数椐主备系统,例如ZooKeeper, 而Paxos算法 则是用于构建一个分布式的一致性状态机系统,

参考:
Zookeeper系列(5)–ZAB协议,消息广播,崩溃恢复,数据同步


ZK中的核心概念

1、集群角色:Leader、Follower、Observer

2、会话(session):指客户端会话,客户端与服务器之间的一个TCP长连接,通过这个连接进行心跳检测和Watch事件通知
TCP长连接与短连接(参考【TCP长连接和短连接的区别】):

  • TCP短连接:数据发送完成后就关闭连接,下次发送数据时重新建立连接,适用于连接频率很低的情况(比如网页访问)
  • TCP长连接:数据发送完后,并不关闭连接,通过相互发送校验包保持连接,再次发送数据时不用再重新建立连接,适用于连接频率很高的情况

3、数据节点(Znode):数据节点,持久节点(持久顺序节点)和临时节点(临时顺序节点)(实现分布式锁等的重要特性)两类

4、版本:Znode版本、子节点版本、ACL版本(保证原子性)

Zookeeper会为每个Znode维护一个叫作Stat的数据结构,结构如图:存在三个版本信息:

  • version:znode数据的修改次数
  • cversion:znode子节点修改次数
  • aversion:znode的ACL修改次数

version是表示对数据节点数据内容的变更次数,强调的是变更次数,因此就算数据内容的值没有发生变化,version的值也会递增。采用CAS操作保证原子性。

5、Watcher:用户在指定节点上注册一些Watcher,事件触发时,会通知到订阅的客户端

6、ACL(Access Control Lists):权限控制,保证数据的安全


ZK的高可用:内存模型 + 数据快照 + ZXID事务日志存储

ZK内存模型

Zookeeper的数据模型是树结构,在内存数据库中,存储了整棵树的内容,包括所有的节点路径、节点数据、ACL信息,Zookeeper会定时将这个数据存储到磁盘上。

  • DataTree
    DataTree是内存数据存储的核心,是一个树结构,代表了内存中一份完整的数据。DataTree不包含任何与网络、客户端连接及请求处理相关的业务逻辑,是一个独立的组件。
  • DataNode
    DataNode是数据存储的最小单元,其内部除了保存了结点的数据内容、ACL列表、节点状态之外,还记录了父节点的引用和子节点列表两个属性,其也提供了对子节点列表进行操作的接口。
  • ZKDatabase
    Zookeeper的内存数据库,管理Zookeeper的所有会话、DataTree存储和事务日志。ZKDatabase会定时向磁盘dump快照数据,同时在Zookeeper启动时,会通过磁盘的事务日志和快照文件恢复成一个完整的内存数据库。

DataTree是整个树的核心,不与任何网络、客户端以及请求事务有关。DataTree利用CurrentHashMap<String,DataNode>的属性nodes来存储着整个树的所有节点以及对应的路径,对于临时节点单独放在一个CurrentHashMap中。DataNode是最小的存储单元,保存着节点的数据,ACL,父节点和子节点列表。
对于目标节点的查找并不是使用树的结构层层查找,而是在DataTree中的属性nodes–CurrentHashMap<String,DataNode>根据路径作为key直接查找DataNode,提高了查找效率。

ZK数据与存储

我们知道Zookeeper是将全量数据存储在内存中,但他是怎样进行容错的呢?当节点崩溃后或重新初始化时,是怎么会发到宕机之前的数据呢?这就需要Zookeeper的数据存储实现。感觉大多数内存存储的组件容错机制都差不多,都是利用快照和事务日志来保证节点宕机恢复工作。比如:zookeeper,HDFS的namenode,redis,都是采用快照+事务日志来进行数据持久化,来实现底层数据的一致性。

事务日志

在配置Zookeeper集群时需要配置dataDir目录,其用来存储事务日志文件。也可以为事务日志单独分配一个文件存储目录:dataLogDir。若配置dataLogDir为/home/admin/zkData/zk_log,那么Zookeeper在运行过程中会在该目录下建立一个名字为version-2的子目录,该目录确定了当前Zookeeper使用的事务日志格式版本号,当下次某个Zookeeper版本对事务日志格式进行变更时,此目录也会变更,即在version-2子目录下会生成一系列文件大小一致(64MB)的文件。

事务日志记录了对Zookeeper的操作,命名为log.ZXID,后缀是一个事务ID。并且是写入该事务日志文件第一条事务记录的ZXID,使用ZXID作为文件后缀,可以帮助我们迅速定位到某一个事务操作所在的事务日志。同时,使用ZXID作为事务日志后缀的另一个优势是:ZXID本身由两部分组成,高32位代表当前leader周期(epoch),低32位则是真正的操作序列号,因此,将ZXID作为文件后缀,我们就可以清楚地看出当前运行时的zookeeper的leader周期。

事务日志的写入是采用了磁盘预分配的策略。因为事务日志的写入性能直接决定看Zookeeper服务器对事务请求的响应,也就是说事务写入可被看做是一个磁盘IO过程,所以为了提高性能,避免磁盘寻址seek所带来的性能下降,所以zk在创建事务日志的时候就会进行文件空间“预分配”,即:在文件创建之初就想操作系统预分配一个很大的磁盘块,默认是64M,而一旦已分配的文件空间不足4KB时,那么将会再次进行预分配,再申请64M空间。

数据快照

数据快照是Zookeeper数据存储中非常核心的运行机制,数据快照用来记录Zookeeper服务器上某一时刻的全量内存数据内容,并将其写入指定的磁盘文件中。也是使用ZXID来作为文件 后缀名,并没有采用磁盘预分配的策略,因此数据快照文件在一定程度上反映了当前zookeeper的全量数据大小。

与事务文件类似,Zookeeper快照文件也可以指定特定磁盘目录,通过dataDir属性来配置。若指定dataDir为/home/admin/zkData/zk_data,则在运行过程中会在该目录下创建version-2的目录,该目录确定了当前Zookeeper使用的快照数据格式版本号。在Zookeeper运行时,会生成一系列文件。

针对客户端的每一次事务操作,Zookeeper都会将他们记录到事务日志中,同时也会将数据变更应用到内存数据库中,Zookeeper在进行若干次(snapCount)事务日志记录后,将内存数据库的全量数据Dump到本地文件中,这就是数据快照。

过半随机策略

每进行一次事务记录后,Zookeeper都会检测当前是否需要进行数据快照。理论上进行snapCount次事务操作就会开始数据快照,但是考虑到数据快照对于Zookeeper所在机器的整体性能的影响,需要避免Zookeeper集群中所有机器在同一时刻进行数据快照。因此zk采用“过半随机”的策略,来判断是否需要进行数据快照。即:符合如下条件就可进行数据快照:
logCount > (snapCount / 2 + randRoll) randRoll位1~snapCount / 2之间的随机数。这种策略避免了zk集群的所有机器在同一时刻都进行数据快照,影响整体性能。

进行快照

开始快照时,首先关闭当前日志文件(已经到了该快照的数了),重新创建一个新的日志文件,创建单独的异步线程来进行数据快照以避免影响Zookeeper主流程,从内存中获取zookeeper的全量数据和校验信息,并序列化写入到本地磁盘文件中,以本次写入的第一个事务ZXID作为后缀。

数据恢复

在Zookeeper服务器启动期间,首先会进行数据初始化工作,用于将存储在磁盘上的数据文件加载到Zookeeper服务器内存中。
数据恢复时,会加载最近100个快照文件(如果没有100个,就加载全部的快照文件)。之所以要加载100个,是因为防止最近的那个快照文件不能通过校验。在逐个解析过程中,如果正确性校验通过之后,那么通常就只会解析最新的那个快照文件,但是如果校验和发现最先的那个快照文件不可用,那么就会逐个进行解析,直到将这100个文件全部解析完。如果将所有的快照文件都解析后还是无法恢复出一个完整的“DataTree”和“sessionWithTimeouts”,则认为无法从磁盘中加载数据,服务器启动失败。当基于快照文件构建了一个完整的DataTree实例和sessionWithTimeouts集合了,此时根据这个快照文件的文件名就可以解析出最新的ZXID,该ZXID代表了zookeeper开始进行数据快照的时刻,然后利用此ZXID定位到具体事务文件从哪一个开始,然后执行事务日志对应的事务,恢复到最新的状态,并得到最新的ZXID。

参考:
Zookeeper系列(4)–ZK概述,数据模型,节点特性,Watcher机制、ACL及数据存储
zookeeper的zab协议工作原理之 崩溃恢复模式


ZK开源客户端

  • ZkClient
  • Curator

Curator解决了很多ZooKeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException等,通过ZooKeeper原生API,提供了一套易用性和可读性更强的Fluent风格的客户端API框架。除此之外,Curator还提供了还提供了ZooKeeper各种应用场景(Recipe,如共享锁服务、Master选举机制和分布式计数器等)的抽象封装。


ZK的典型应用场景

Zookeeper的两大特性(节点特性和watcher机制):

  • 客户端如果对Zookeeper的数据节点注册Watcher监听,那么当该数据及诶单内容或是其子节点列表发生变更时,Zookeeper服务器就会向订阅的客户端发送变更通知。
  • 对在Zookeeper上创建的临时节点,一旦客户端与服务器之间的会话失效,那么临时节点也会被自动删除。
    ZooKeeper是一个典型的发布/订阅模式的高可用的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布与订阅。另一方面,通过对ZooKeeper中丰富的数据节点类型进行交叉使用,配合Watcher通知机制,利用这两大特性,可以非常方便地构建一系列分布式应用中都会涉及的核心功能,如
  • 数据发布/订阅
  • 负载均衡
  • 命名服务
  • 分布式协调/通知
  • 集群管理
  • Master选举
  • 分布式锁
  • 分布式队列

几种应用场景的实现

负载均衡

基本原理是,每个应用的Server启动时创建一个EPHEMERAL(临时)节点,应用客户端通过读取节点列表获得可用服务器列表,并订阅节点事件,有Server宕机断开时触发事件,客户端监测到后把该Server从可用列表中删除

命名服务

基本原理:通过调用Zookeeper节点创建的API接口就可以创建一个顺序节点,并且在API返回值中会返回这个节点的完整名字,利用此特性,可以生成全局ID,其步骤如下

  • 1.客户端根据任务类型,在指定类型的任务下通过调用接口创建一个顺序节点,如"job-"。
  • 2.创建完成后,会返回一个完整的节点名,如"job-00000001"。
  • 3.客户端拼接type类型和返回值后,就可以作为全局唯一ID了,如"type2-job-00000001"。

Master选举

基本原理,利用Zookeeper的一致性,能够很好地保证在分布式高并发情况下节点的创建一定能够保证全局唯一性,即Zookeeper将会保证客户端无法重复创建一个已经存在的数据节点(由其分布式数据的一致性保证)。
首先创建/master_election/2016-11-12节点,客户端集群每天会定时往该节点下创建临时节点,如/master_election/2016-11-12/binding,这个过程中,只有一个客户端能够成功创建,此时其变成master,其他节点都会在节点/master_election/2016-11-12上注册一个子节点变更的Watcher,用于监控当前的Master机器是否存活,一旦发现当前Master挂了,其余客户端将会重新进行Master选举

分布式锁

实现方案:

  • 1、客户端调用create接口常见类似于/shared_lock/[Hostname]-请求类型-序号的临时顺序节点。
  • 2、客户端调用getChildren接口获取所有已经创建的子节点列表(不注册任何Watcher)。
  • 3、如果无法获取共享锁,就调用exist接口来对比自己小的节点注册Watcher。对于读请求:向比自己序号小的最后一个写请求节点注册Watcher监听。对于写请求:向比自己序号小的最后一个节点注册Watcher监听。
  • 4、等待Watcher通知,继续进入步骤2。
    此方案改动主要在于:每个锁竞争者,只需要关注/shared_lock节点下序号比自己小的那个节点是否存在即可。

分布式队列

① FIFO先入先出,先进入队列的请求操作先完成后,才会开始处理后面的请求。FIFO队列就类似于全写的共享模型,所有客户端都会到/queue_fifo这个节点下创建一个临时节点,如/queue_fifo/host1-00000001。

创建完节点后,按照如下步骤执行。

  • 1、通过调用getChildren接口来获取/queue_fifo节点的所有子节点,即获取队列中所有的元素。
  • 2、确定自己的节点序号在所有子节点中的顺序。
  • 3、如果自己的序号不是最小,那么需要等待,同时向比自己序号小的最后一个节点注册Watcher监听。
  • 4、接收到Watcher通知后,重复步骤1。

② Barrier分布式屏障,最终的合并计算需要基于很多并行计算的子结果来进行,开始时,/queue_barrier节点已经默认存在,并且将结点数据内容赋值为数字n来代表Barrier值,之后,所有客户端都会到/queue_barrier节点下创建一个临时节点,例如/queue_barrier/host1。
创建完节点后,按照如下步骤执行。

  • 1、通过调用getData接口获取/queue_barrier节点的数据内容,如10。
  • 2、通过调用getChildren接口获取/queue_barrier节点下的所有子节点,同时注册对子节点变更的Watcher监听。
  • 3、统计子节点的个数。
  • 4、如果子节点个数还不足10个,那么需要等待。
  • 5、接受到Wacher通知后,重复步骤3

更多:
Zookeeper系列(6)-- Zookeeper的典型应用场景
分布式锁的几种使用方式(redis、zookeeper、数据库)


ZK与Eureka

  • ZooKeeper基于CP构建
  • Eureka基于AP构建

参考:
ZooKeeper是按照CP原则构建的,不适合做Service服务发现
Eureka与ZooKeeper 的比较


ZK知识点总结

Zookeeper学习中的疑难问题总结,很受用
Zookeeper系列二:分布式架构详解、分布式技术详解、分布式事务

猜你喜欢

转载自blog.csdn.net/zangdaiyang1991/article/details/91981642