一、简介
ZooKeeper由雅虎研究院开发,后来捐赠给了Apache。ZooKeeper是一个开源的分布式应用程序协调服务器,其为分布式系统提供一致性服务。其一致性是通过基于Paxos算法的ZAB协议完成的。其主要功能包括:配置维护、域名服务、分布式同步、集群管理等。
zookeeper的官网: http://zookeeper.apache.org
二、设计目的
(1)顺序性
包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
(2)原子性
更新操作只有成功或者失败,没有中间状态。
(3)可靠性
具有简单、健壮、良好的性能、如果消息m被一台服务器接受,那么消息m将被所有服务器接受。
(4)最终一致性
client无论链接那个Server,展示给它的都是同一个视图(数据都是一样)。
(5)实时性
Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
(6)等待无关(wait-free)
慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待
三、工作原理
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做ZAB协议(ZooKeeper Atomic Broadcast protocol)。Zab协议有两种模式,它们分别是恢复模式(Recovery选主)和广播模式(Broadcast同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数
(1)三类角色
Leader 、Follower、Observer
(2)四种状态
LOOKING:当前Server不知道leader是谁,正在搜寻。
LEADING:当前Server即为选举出来的leader。
FOLLOWING:leader已经选举出来,当前Server与之同步。
OBSERVING:observer的行为在大多数情况下与follower完全一致,但是他们不参加选举和投票,而仅仅接受(observing)选举和投票的结果。
四、Leader选举
当集群正在启动过程中,或Leader与超过半数的主机断连后,集群就进入了恢复模式。而恢复模式中最重要的阶段就是Leader选举。
(1)Leader选举中的基本概念
A、myid
这是zk集群中服务器的唯一标识,称为myid。例如,有三个zk服务器,那么编号分别是1,2,3。
B、逻辑时钟
逻辑时钟,Logicalclock,是一个整型数,该概念在选举时称为logicalclock,而在选举结束后称为epoch。即epoch与logicalclock是同一个值,在不同情况下的不同名称。
C、zk状态
zk集群中的每一台主机,在不同的阶段会处于不同的状态。每一台主机具有四种状态。
LOOKING
FOLLOWING
OBSERVING
LEADING
(2) Leader选举算法
在集群启动过程中的Leader选举过程(算法)与Leader断连后的Leader选举过程稍微有一些区别,基本相同。
A、集群启动中的Leader选举
若进行Leader选举,则至少需要两台主机,这里以三台主机组成的集群为例。
在集群初始化阶段,当第一台服务器Server1启动时,其会给自己投票,然后发布自己的投票结果。投票包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0)。由于其它机器还没有启动所以它收不到反馈信息,Server1的状态一直属于Looking,即属于非服务状态。
当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,选举过程如下:
(1) 每个Server发出一个投票。此时Server1的投票为(1, 0),Server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。
(2) 接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
(3) 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下:
- 优先检查ZXID。ZXID比较大的服务器优先作为Leader。
- 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。
对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0)。其首先会比较两者的ZXID,均为0,再比较myid,此时Server2的myid最大,于是Server1更新自己的投票为(2, 0),然后重新投票。对于Server2而言,其无须更新自己的投票,只是再次向集群中所有主机发出上一次投票信息即可。
(4) 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息。对于Server1、Server2而言,都统计出集群中已经有两台主机接受了(2, 0)的投票信息,此时便认为已经选出了新的Leader,即Server2。
(5) 改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。
(6) 添加主机。在新的Leader选举出来后Server3启动,其想发出新一轮的选举。但由于当前集群中各个主机的状态并不是LOOKING,而是各司其职的正常服务,所以其只能是以Follower的身份加入到集群中。
B、断连后的Leader选举
在Zookeeper运行期间,Leader与非Leader服务器各司其职,即便当有非Leader服务器宕机或新加入时也不会影响Leader。但是若Leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮的Leader选举,其过程和启动时期的Leader选举过程基本一致。
假设正在运行的有Server1、Server2、Server3三台服务器,当前Leader是Server2,若某一时刻Server2挂了,此时便开始新一轮的Leader选举了。选举过程如下:
(1) 变更状态。Leader挂后,余下的非Observer服务器都会将自己的服务器状态由FOLLOWING变更为LOOKING,然后开始进入Leader选举过程。
(2) 每个Server会发出一个投票,仍然会首先投自己。不过,在运行期间每个服务器上的ZXID可能是不同,此时假定Server1的ZXID为111,Server3的ZXID为333;在第一轮投票中,Server1和Server3都会投自己,产生投票(1, 111),(3, 333),然后各自将投票发送给集群中所有机器。
(3) 接收来自各个服务器的投票。与启动时过程相同。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
(4) 处理投票。与启动时过程相同。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK。对于Server1而言,它的投票是(1, 111),接收Server3的投票为(3, 333)。其首先会比较两者的ZXID,Server3投票的zxid为333大于Server1投票的zxid的111,于是Server1更新自己的投票为(3, 333),然后重新投票。对于Server3而言,其无须更新自己的投票,只是再次向集群中所有主机发出上一次投票信息即可。
(5) 统计投票。与启动时过程相同。对于Server1、Server2而言,都统计出集群中已经有两台主机接受了(3, 333)的投票信息,此时便认为已经选出了新的Leader,即Server3。
(6) 改变服务器的状态。与启动时过程相同。一旦确定了Leader,每个服务器就会更新自己的状态。Server1变更为FOLLOWING,Server3变更为LEADING。
五、ZAB与Paxos的关系
ZAB协议是Fast Paxos算法的一种工业实现算法。但两者的设计目标不太一样。ZAB协议主要用于构建一个高可用的分布式数据主备系统,例如,Leader挂了,马上就可以选举出一个新的Leader。而Paxos算法则是用于构建一个分布式一致性状态机系统,确保系统中各个节点的状态都是一致的。
另外,ZAB还使用Google的Chubby算法作为分布式锁的实现,而Google的Chubby也是Paxos算法的应用。
六、CAP定理
(1)简介
CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。
- 一致性(C):分布式系统中多个主机之间是否能够保持数据一致的特性。即,当系统数据发生更新操作后,各个主机中的数据仍然处于一致的状态。
- 可用性(A):系统提供的服务必须一直处于可用的状态,即对于用户的每一个请求,系统总是可以在有限的时间内对用户做出响应。
- 分区容错性(P):分布式系统在遇到任何网络分区故障时,仍能够保证对外提供满足一致性和可用性的服务。
对于分布式系统,网络环境相对是不可控的,出现网络分区是不可避免的,因此系统必须具备分区容错性。但其并不能同时保证一致性与可用性。CAP原则对于一个分布式系统来说,只可能满足两项,即要么CP,要么AP
七、ZK与CP
zk遵循的是CP原则,即保证了一致性,但牺牲了可用性。体现在哪里呢?
当Leader宕机后,zk集群会马上进行新的Leader的选举。但选举时长在30-200毫秒间,整个选举期间zk集群是不接受客户端的读写操作的,即zk集群是处于瘫痪状态的。所以,其不满足可用性。