一、ZK的基本概念
1、集群角色
Leader服务器 整个Zookeeper集群工作机制中的核心 ,不接受client的请求,主要负责进行投票的发起和决议,更新系统状态。
Follower服务器 Zookeeper集群状态的跟随者,用于接受客户请求并向客户端返回结果,参与leader发起的投票。
ObServer服务器 充当一个观察者的角色,ObServer可以接收客户端连接,将写请求转发leader节点。但ObServer不参加投票过程,只同步leader的状态。ObServer的目的是为了扩展系统,提高读取速度。
2、会话
会话是指客户端和ZooKeeper服务器的连接,ZooKeeper中的会话叫Session,客户端靠与服务器建立一个TCP的长连接来维持一个Session,客户端在启动的时候首先会与服务器建立一个TCP连接,通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能向Zookeeper服务器发送请求并获得响应。
3、数据节点
Zookeeper中的节点有两类:
集群中的一台机器成为一个节点
数据模型中的数据单元Znode,分为持久节点和临时节点
Zookeeper的数据模型是一棵树,树的节点就是Znode,Znode中可以保存信息。 //和根文件系统类似,开发主要是和数据节点打交道
zk的数据是保存在内存中的。
图2:
zk的数据模型特点:
1.每个节点(ZNode)中存储的是同步相关的数据(这是ZooKeeper设计的初衷,数据量很小,大概B到KB量级),例如状态信息、配置内容、位置信息等。
2.一个ZNode维护了一个状态结构,该结构包括:版本号、ACL变更、时间戳。每次ZNode数据发生变化,版本号都会递增,这样客户端的读请求可以基于版本号来检索状态相关数据。
3.每个ZNode都有一个ACL,用来限制是否可以访问该ZNode。
4.在一个命名空间中,对ZNode上存储的数据执行读和写请求操作都是原子的。
5.客户端可以在一个ZNode上设置一个监视器(Watch),如果该ZNode数据发生变更,ZooKeeper会通知客户端,从而触发监视器中实现的逻辑的执行。
6.每个客户端与ZooKeeper连接,便建立了一次会话(Session),会话过程中,可能发生CONNECTING、CONNECTED和CLOSED三种状态。
7.ZooKeeper支持临时节点(Ephemeral Nodes)的概念,它是与ZooKeeper中的会话(Session)相关的,如果连接断开,则该节点被删除。
4、版本
ZK中的版本,是用来记录节点数据或者是节点的子节点列表或者是权限信息的修改次数
如果一个节点的version是1,那就代表说这个节点从创建以来被修改了一次,一般基于版本实现分布式锁。
对于每个ZNode,Zookeeper都会为其维护一个叫作Stat的数据结构,Stat记录了这个ZNode的三个数据版本,如下:
version 当前数据节点数据内容的版本号
cversion 当前数据节点子节点的版本号
aversion 当前数据节点ACL变更版本号
5、分布式锁的实现方式
1.建立一个节点,假如名为:lock 。节点类型为持久节点(PERSISTENT)
2.每当进程需要访问共享资源时,会调用分布式锁的lock()或tryLock()方法获得锁,这个时候会在第一步创建的lock节点下建立相应的顺序子节点,节点类型为临时顺序节点(EPHEMERAL_SEQUENTIAL),通过组成特定的名字name+lock+顺序号。
3.在建立子节点后,对lock下面的所有以name开头的子节点进行排序,判断刚刚建立的子节点顺序号是否是最小的节点,假如是最小节点,则获得该锁对资源进行访问。
4.假如不是该节点,就获得该节点的上一顺序节点,并给该节点是否存在注册监听事件。同时在这里阻塞。等待监听事件的发生,获得锁控制权。
5.当调用完共享资源后,调用unlock()方法,关闭zk,进而可以引发监听事件,释放该锁。
实现的分布式锁是严格的按照顺序访问的并发锁。
6、watcher事件监听器
ZooKeeper允许用户在指定节点上注册一些watcher,当数据节点发生变化的时候,Zookeeper服务器会把这个变化的通知发送给感兴趣的客户端。
图3:
两个客户端都在zookeeper集群中注册了watcher(事件监听器),那么当zk中的节点数据发生变化的时候,zk会把这一变化的通知发送给客户端,当客户端收到这个变化通知的时候,它可以再回到zk中,去取得这个数据的详细信息。
7、ACL权限控制
ACL是Access Control Lists,ZooKeeper采用ACL策略来进行权限控制,有以下权限:
- CREATE:创建子节点的权限
- READ:获取节点数据和子节点列表的权限
- WRITE:更新节点数据的权限
- DELETE:删除子节点的权限
- ADMIN:设置节点ACL的权限
8、zk提供的分布式一致性
1.顺序一致性,从同一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到Zookeeper中去。
2.原子性,所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,即整个集群要么都成功应用了某个事务,要么都没有应用。
3.单一视图,无论客户端连接的是哪个Zookeeper服务器,其看到的服务端数据模型都是一致的。
4.可靠性,一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直被保留,除非有另一个事务对其进行了变更。
5.实时性,Zookeeper保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
二、Zab与Paxos算法
Zab协议Zookeeper Atomic Broadcast(ZAB,Zookeeper原子消息广播协议)作为zk其数据一致性的核心算法。ZAB协议是为Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。
zk依赖zab协议实现了一种主备模式的系统架构来保持集群中各副本之间的数据的一致性。使用一个单一的诸进程来接收并处理客户端的所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以事务Proposal的形式广播到所有的副本进程中,ZAB协议的主备模型架构保证了同一时刻集群中只能够有一个主进程来广播服务器的状态变更,因此能够很好地处理客户端大量的并发请求。
ZAB协议的核心是定义了对于那些会改变Zookeeper服务器数据状态的事务请求的处理方式,即:所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,余下的服务器则称为Follower服务器,Leader服务器负责将一个客户端事务请求转化成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器,之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进行提交。
1、Zab协议
ZAB一些包括两种基本的模式:崩溃恢复和消息广播。
Leader出现网络中断、崩溃退出、重启等异常情况下。Zab协议进入恢复模式并产生新的Leader服务器,当选举产生了新的Leader之后并且集群中过半的机器与该Leader服务器同步状态(同步数据)之后,Zab退出恢复模式
当集群中已经有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就可以进入消息广播模式
新集群(遵守Zab)加入集群,集群中已经存在一个Leader负责消息广播。新机器自觉地进入数据恢复模式:找到Leader所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。
ZK只允许Leader进行事务处理。Leader服务器在接收到客户端的事务请求后,会生成对应的事务提议并发起一轮广播协议,而如果集群中的其他机器收到客户端的事务请求后,那么这些非Leader服务器会首先将这个事务请求转发给Leader服务器。
(崩溃)恢复模式:Leade挂了进入该模式/或者新机器join集群/或者集群中已经不存在过半的服务器与Leader服务器保持正常通信
消费广播模式:过半Follower与Leader进行状态同步完成后。
1.1、消息广播
ZAB协议的消息广播过程使用原子广播协议,类似于一个二阶段提交过程,针对客户端的事务请求,Leader服务器会为其生成对应的事务Proposal,并将其发送给集群中其余所有的机器,然后再分别收集各自的选票,最后进行事务提交。
图2-1
在ZAB的二阶段提交过程中,移除了中断逻辑,所有的Follower服务器要么正常反馈Leader提出的事务Proposal,要么就抛弃Leader服务器,同时,ZAB协议将二阶段提交中的中断逻辑移除意味着我们可以在过半的Follower服务器已经反馈Ack之后就开始提交事务Proposal,而不需要等待集群中所有的Follower服务器都反馈响应,但是,在这种简化的二阶段提交模型下,无法处理Leader服务器崩溃退出而带来的数据不一致问题,因此ZAB采用了崩溃恢复模式来解决此问题,另外,整个消息广播协议是基于具有FIFO特性的TCP协议来进行网络通信的,因此能够很容易保证消息广播过程中消息接受与发送的顺序性。再整个消息广播过程中,Leader服务器会为每个事务请求生成对应的Proposal来进行广播,并且在广播事务Proposal之前,Leader服务器会首先为这个事务Proposal分配一个全局单调递增的唯一ID,称之为事务ID(ZXID),由于ZAB协议需要保证每个消息严格的因果关系,因此必须将每个事务Proposal按照其ZXID的先后顺序来进行排序和处理。
1.2、崩溃恢复
在Leader服务器出现崩溃,或者由于网络原因导致Leader服务器失去了与过半Follower的联系,那么就会进入崩溃恢复模式,在ZAB协议中,为了保证程序的正确运行,整个恢复过程结束后需要选举出一个新的Leader服务器,因此,ZAB协议需要一个高效且可靠的Leader选举算法,从而保证能够快速地选举出新的Leader,同时,Leader选举算法不仅仅需要让Leader自身知道已经被选举为Leader,同时还需要让集群中的所有其他机器也能够快速地感知到选举产生的新的Leader服务器。
1.3、基本特性
AB协议规定了如果一个事务Proposal在一台机器上被处理成功,那么应该在所有的机器上都被处理成功,哪怕机器出现故障崩溃。ZAB协议需要确保那些已经在Leader服务器上提交的事务最终被所有服务器都提交,假设一个事务在Leader服务器上被提交了,并且已经得到了过半Follower服务器的Ack反馈,但是在它Commit消息发送给所有Follower机器之前,Leader服务挂了。
图2-2:
在集群正常运行过程中的某一个时刻,Server1是Leader服务器,其先后广播了P1、P2、C1、P3、C2(C2是Commit Of Proposal2的缩写),其中,当Leader服务器发出C2后就立即崩溃退出了,针对这种情况,ZAB协议就需要确保事务Proposal2最终能够在所有的服务器上都被提交成功,否则将出现不一致。
ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务。如果在崩溃恢复过程中出现一个需要被丢弃的提议,那么在崩溃恢复结束后需要跳过该事务Proposal
图2-3:
假设初始的Leader服务器Server1在提出一个事务Proposal3之后就崩溃退出了,从而导致集群中的其他服务器都没有收到这个事务Proposal,于是,当Server1恢复过来再次加入到集群中的时候,ZAB协议需要确保丢弃Proposal3这个事务。
在上述的崩溃恢复过程中需要处理的特殊情况,就决定了ZAB协议必须设计这样的Leader选举算法:
能够确保提交已经被Leader提交的事务的Proposal,同时丢弃已经被跳过的事务Proposal。如果让Leader选举算法能够保证新选举出来的Leader服务器拥有集群中所有机器最高编号(ZXID最大)的事务Proposal,那么就可以保证这个新选举出来的Leader一定具有所有已经提交的提议,更为重要的是如果让具有最高编号事务的Proposal机器称为Leader,就可以省去Leader服务器查询Proposal的提交和丢弃工作这一步骤了。
1.4、数据同步
Leader选举完成后。在正式开始工作前,Leader服务器首先会确认日志中的所有Proposal是否都已经被集群中的过半机器提交了,即是否完成了数据同步。Leader服务器需要确所有的Follower服务器都能够接收到每一条事务Proposal,并且能够正确地将所有已经提交了的事务Proposal应用到内存数据库中。Leader服务器会为每个Follower服务器维护一个队列,并将那些没有被各Follower服务器同步的事务以Proposal消息的形式逐个发送给Follower服务器,并在每一个Proposal消息后面紧接着再发送一个Commit消息,以表示该事务已经被提交,等到Follower服务器将所有其尚未同步的事务Proposal都从Leader服务器上同步过来并成功应用到本地数据库后,Leader服务器就会将该Follower服务器加入到真正的可用Follower列表并开始之后的其他流程。
ZAB协议如何处理需要丢弃的事务Proposal:
ZXID是一个64位的数字,其中32位可以看做是一个简单的单调递增的计数器,针对客户端的每一个事务请求,Leader服务器在产生一个新的事务Proposal时,都会对该计数器进行加1操作,而高32位则代表了Leader周期epoch的编号,每当选举产生一个新的Leader时,就会从这个Leader上取出其本地日志中最大事务Proposal的ZXID,并解析出epoch值,然后加1,之后以该编号作为新的epoch,低32位则置为0来开始生成新的ZXID,ZAB协议通过epoch号来区分Leader周期变化的策略,能够有效地避免不同的Leader服务器错误地使用不同的ZXID编号提出不一样的事务Proposal的异常情况。
当一个包含了上一个Leader周期中尚未提交过的事务Proposal的服务器启动时,其肯定无法成为Leader,因为当前集群中一定包含了一个Quorum(过半)集合,该集合中的机器一定包含了更高epoch的事务的Proposal,因此这台机器的事务Proposal并非最高,也就无法成为Leader。
2、ZAB协议原理
ZAB主要包括消息广播和崩溃恢复两个过程,进一步可以分为三个阶段,分别是发现(Discovery)、同步(Synchronization)、广播(Broadcast)阶段。ZAB的每一个分布式进程会循环执行这三个阶段,称为主进程周期。
发现,选举产生PL(prospective leader),PL收集Follower epoch(cepoch),根据Follower的反馈,PL产生newepoch(每次选举产生新Leader的同时产生新epoch)。
同步,PL补齐相比Follower多数派缺失的状态、之后各Follower再补齐相比PL缺失的状态,PL和Follower完成状态同步后PL变为正式Leader(established leader)。
广播,Leader处理客户端的写操作,并将状态变更广播至Follower,Follower多数派通过之后Leader发起将状态变更落地(deliver/commit)。
在正常运行过程中,ZAB协议会一直运行于阶段三来反复进行消息广播流程,如果出现崩溃或其他原因导致Leader缺失,那么此时ZAB协议会再次进入发现阶段,选举新的Leader。
3、运行分析
每个进程都有可能处于如下三种状态之一
LOOKING:Leader选举阶段。
FOLLOWING:Follower服务器和Leader服务器保持同步状态。
LEADING:Leader服务器作为主进程领导状态。
所有进程初始状态都是LOOKING状态,此时不存在Leader,此时,进程会试图选举出一个新的Leader,之后,如果进程发现已经选举出新的Leader了,那么它就会切换到FOLLOWING状态,并开始和Leader保持同步,处于FOLLOWING状态的进程称为Follower,LEADING状态的进程称为Leader,当Leader崩溃或放弃领导地位时,其余的Follower进程就会转换到LOOKING状态开始新一轮的Leader选举。
一个Follower只能和一个Leader保持同步,Leader进程和所有与所有的Follower进程之间都通过心跳检测机制来感知彼此的情况。若Leader能够在超时时间内正常收到心跳检测,那么Follower就会一直与该Leader保持连接,而如果在指定时间内Leader无法从过半的Follower进程那里接收到心跳检测,或者TCP连接断开,那么Leader会放弃当前周期的领导,比你转换到LOOKING状态,其他的Follower也会选择放弃这个Leader,同时转换到LOOKING状态,之后会进行新一轮的Leader选举,并在选举产生新的Leader之后开始新的一轮主进程周期。
4、Zab与paxos的联系和区别
联系:
都存在一个类似于Leader进程的角色,由其负责协调多个Follower进程的运行。
Leader进程都会等待超过半数的Follower做出正确的反馈后,才会将一个提议进行提交。
在ZAB协议中,每个Proposal中都包含了一个epoch值,用来代表当前的Leader周期,在Paxos算法中,同样存在这样的一个标识,名字为Ballot。
区别:
Paxos算法中,新选举产生的主进程会进行两个阶段的工作,第一阶段称为读阶段,新的主进程和其他进程通信来收集主进程提出的提议,并将它们提交。第二阶段称为写阶段,当前主进程开始提出自己的提议。
ZAB协议在Paxos基础上添加了同步阶段,此时,新的Leader会确保存在过半的Follower已经提交了之前的Leader周期中的所有事务Proposal。
ZAB协议主要用于构建一个高可用的分布式数据主备系统,而Paxos算法则用于构建一个分布式的一致性状态机系统。
三、其他
zk类似于人体大脑,本身没有什么功能,只是负责协调。联络各个子系统的功能。
主要功能
维护配置信息:分布式系统中公共配置文件更新后通知各个client/APP
命名:Providers向zk注册接口、地址、端口等信息,consumers通过zk获取Providers的信息
分布式同步(分布式锁):协调资源
提供组服务:创建组、加入组成员、删除组成员。主要通过心跳机制实现。
备注: paxos、basic paxos、fast paxos请参考博客:[ http://blog.csdn.net/xhh198781/article/details/10949697 ]
参考博客
https://blog.csdn.net/guchuanyun111/article/details/52092703
https://blog.csdn.net/jiuqiyuliang
https://www.cnblogs.com/yuyijq/p/3424473.html
http://www.cnblogs.com/raphael5200/p/5285380.html
https://www.cnblogs.com/leesf456/p/6012777.html //paxos与zab