What is ZooKeeper? ZooKeeper是一个开放源代码的分布式协调服务,出自«分布式一致性原理与实践»。对于像我这样的新手来说,这句话就是在扯淡。 还记得当初刚学Spring,网上各种都在说的Spring的IOC,AOP的优越,但是讲半天也没有说明Spring到底是做什么的。在«Spring实战»中,开门见山的讲明了Spring就是用来解隅的。带着这个目的去学习Spring,就有了方向,你就会逐渐明白Spring如何解隅,IOC和AOP。这就是好书给人的感觉。本文适合菜鸟,高手止步。

ZooKeeper

在日常的应用系统开发中,会经常存在这样的需求:系统中需要使用一些通用的配置中心,例如机器列表等,这些配置文件通常内容较小,内容会发生动态变化,而且各个机器共享配置。我们可以将这些内容放在一个机器A上,其余的机器去这个机器A上取这些信息,而机器A则管理配置文件。 但是这样存在一个问题如果机器A宕机,则整个服务都会崩溃,所以就需要将这些配置文件放在多台机器上,然而如何保持这些机器中内容的一致性,这就是一个典型的ZooKeeper提供的服务:数据发布与订阅。 这仅仅是ZooKeeper提供的一个功能,ZooKeeper作为一个分布式协调服务框架,还可以用来做负载均衡,命名服务,实现分布式锁,分布式队列等。 ZooKeeper实现这些功能主要靠ZNode和ZAB

ZNode

在分布式中,通常指的"节点"指组成集群的每一台机器。在ZooKeeper中,“节点"分为两类,第一类同样指机器,称为机器节点。第二类指的是数据模型中的数据单元,称为数据节点ZNode。 ZooKeeper将内容保存在每台机器的内存中,如何保存这些东西,就用ZNode数据模型来实现。ZNode数据模型是一颗树,类似Linux下的文件系统。不同的是没有Linux的inode节点,目录和文件之分。在ZNode中,每个ZNode都是一个目录暨文件,ZNode即可以有自己的文件内容,也可以有自己的子目录。 ZNode通过保持ZNode内容的一致性,来实现分布式锁,分布式队列等。

ZAB

ZAB协议用于保持ZooKeeper集群的一致性。

ZooKeeper集群中所有的事物请求必须由全局唯一的一台服务器来协调处理,称为Leader服务器,余下的服务器称为Follower服务器。

ZAB协议主要包含崩溃恢复内容广播两方面。崩溃恢复指在ZooKeeper启动和Leader服务器崩溃时产生新的Leader服务器。内容广播指Leader服务器向Follower服务器发送事务请求并通过同步来保持状态一致。

ZAB有一个事物编号ZXID,共64位,前32位为一个递增的计数器count,后32位代表当前的Leader周期epoch,每换一个Leader,Leader周期加1,前32位的计数器清零。同一个Leader内,每完成一个事物,计数器加1。以此来保证事物ZXID的唯一性。

ZAB算法主要有三个步骤,如下:

  • 发现
  1. Follower F将自己最后接受事物Proposal的Epoch值发给准Leader L。
  2. 当准Leader L接受到过半Follower的epoch值后,准LeaderL会生成new epoch值给这些过半的Follower。这个new epoch 是接收的Follower中的最大的epoch + 1。
  3. 当Follower接受到准Leader L的new epoch值后,检测当前的epoch。如果 epoch < new epoch,将 epoch <- new epoch,同时反馈ACK信息。在这个反馈信息中包含该Follower的历史Proposal集合
  4. 准Leader收到来自过半Follower的确认消息ACK后,Leader L从其余机器中选出一个Follwer F。这个Follower具有其余机器中最大的epoch 和 count。
  • 同步
  1. Leader L将自己的new epoch和历史Proposal集合发送给所有的Follower。
  2. Follower检测自己的epoch 和 new epoch,如果不相同,就说明此Follower在上一轮或更上一轮的过程中,无法参与本轮同步。如果相同,Follower会处理历史Proposal集合中的事物,处理完毕后,反馈给Leader。
  3. 如果Leader接受到来自过半Follower的反馈信息,向所有Follower发送commit信息。完成阶段二。
  4. 当Follower收到来自Leader的Commit消息后,依次处理并提交之前的proposal事物。
  • 广播 完成同步阶段后,Leader可以正式开始接受客户端新的事物请求。过程类似2PC
  1. Leader L接受到客户端新的事物请求后,生成Proposal包括<e’, <v, z»。并向Follower广播。
  2. Follower根据消息接收的先后次序来处理这些来自Leader的事物Proposal,之后反馈给Leader。
  3. 当Leader接受到过半Follower的ACK后,发送Commit请求给所有Follower,进行事物提交。
  4. 当Follower F接受到来自Leader的Commit消息后,开始提交事物。
对比Paxos
  • ZAB和Paxos目的不完全相同:

ZAB协议主要用于构建一个高可用的分布式数据主备系统,例如ZooKeeper。 Paxos则是用于构建一个分布式的一致性状态机系统,强调一致性,完整的Paxos算法很难在工程上去实现。

  • 两者都存在一个Leader角色
  • Leader进程会等待超过半数Follower做出正确反馈后,才会将一个议案提交。
  • ZAB协议中,每个Proposal包含一个epoch值,表示当前的Leader周期。Paxos算法中同样有这样一个标识,名字为Ballot