目录
一、Zab协议
zab协议全称Zookeeper Atomic Broadcast(zookeeper原子广播)。zookeeper是通过zab协议来保证分布式事务的最终一致性
基于zab协议,zookeeper集群中的角色主要由以下几类:
角色 | 描述 |
领导者(Leader) | 领导者负责进行投票的发起和决议,更新系统状态 |
跟随者(Follower) | Follower用于接收客户请求并向客户端返回结果,在选举过程中参与投票 |
观察者(Observer) | Observer可以接受客户端连接,将写请求转发给leader节点,但Observer不参加投票过程,只同步leader的状态。Observer的目的是为了扩展系统,提高读取速度。 |
客户端(Client) | 请求发起者 |
observer角色及其配置
observer角色的特点:不参与选举,不参数集群中写数据的ack反馈
为了使用observer角色,在任何想变成observer角色的配置文件中加入如下配置:
peerType=observer
并在所有server的配置文件中,配置成observer模式的server的那行配置追加:
server.1=127.0.0.1:2283:3389:observer
zookeeper集群中,不论什么角色,每个节点都会保存集群当中数据的一份副本。
ZAB广播模式工作原理,通过类似两阶段提交协议的方式解决数据一致性
- leader从客户端收到一个写请求
- leader生成一个新的事务并为这个事务生成一个唯一的ZXID
- Leader将这个事务提议(propose)发送给所有的follows节点
- follower节点将收到的事务请求加入到历史队列中,并发送ack给leader
- 当leader收到大多数follower(半数以上节点)的ack消息,leader会发送commit请求
- 当follower收到commit请求时,从历史队列中将事务请求commit
二、zookeeper的选举
2.1服务器的状态
- looking:寻找leader状态。当服务器处于该状态时,它会人为当前集群中没有leader,因此需要进入leader选举状态。
- leading:领导者状态。表明当前服务器角色是leader。
- following:跟随者状态。表明当前服务器角色是follower。
- observing:观察者状态。表明当前服务器角色是observer。
2.2 服务器启动时期的leader选举
在集群初始化阶段,当有一台服务器server1启动时,其单独无法进行和完成leader选举,当第二台服务器server2启动时,此时两台机器可以相互通信,每台机器都试图找到leader,于是进入了leader选举过程:
- 每个server发出一个投票。由于是初始状态,server1和server2都会将自己作为leader服务器来进行投票,每次投票会包含所推举的服务器的myid和zxid,使用(myid,zxid)来表示,此时server1的投票为(1,0),server2的投票为(2,0),然后各自将这个投票发给集群中的其他机器。
- 集群中的每台服务器接收来自集群中各个服务器的投票。
- 处理投票:针对每一个投票,服务器都需要将别人的投票和自己的投票进行pk,规则如下(①优先检查zxid,zxid比较大的服务器优先作为leader。②如果zxid相同,那么就比较myid。myid较大的服务器作为leader服务器。------对于server1而言,它的投票是(1,0),接收server2的投票为(2,0),首先会比较两者的zxid,均为0,再比较myid,此时server2的myid最大,于是更新自己的投票为(2,0),然后重新投票,对于server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出一次投票信息即可。)
- 统计投票,每次投票后,服务器都会统计投票信息,判断是否已经有过半数机器接收到相同的投票信息,对于server1、server2而言,都统计出集群中已经有两台机器接收了(2,0)的投票信息,此时便认为已经选出了leader。
- 改变服务器状态。一旦确定了leader,每个服务器就会更新自己的状态,如果是follower,那么就会变为following,如果是leader,就会变为leading。
简单地说,通常哪台服务器上的数据越新(ZXID会越大),那么越有可能成为Leader,原因很简单,数据越新,那么它的ZXID也就越大,也就越能够保证数据的恢复。当然,如果集群中有几个服务器有相同的ZXID,那么myID较大的那台服务器成为Leader。
2.3服务器运行时期的leader选举
在zookeeper运行期间,leader与非leader服务器各司其职,即便当有非leader服务器宕机或新的机器加入,此时也不会影响leader,但是一旦leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮leader选举,其过程和启动时期的leader选举过程基本一致。
假设正在运行的有server1、server2、server3三台服务器,当前leader是server2,若某一时刻leader挂了,此时便开始leader选举,选举过程如下:
- 变更状态:leader挂掉后,余下的服务器都会将自己的服务器状态变更为looking,然后开始进入leader选举过程。
- 每个server会发起一个投票。在运行期间,每个服务器上的zxid可能不同,此时假定server1的zxid为122,server3的zxid为122,在第一轮投票中,server1和server3都会投自己,产生投票(1,122)(3,122),然后各自将投票发送给集群中所有机器。
- 接收来自各个服务器的投票,与启动过程一样。
- 处理投票,与启动过程相同,此时server3将会成为leader。
- 统计投票,与启动过程相同。
- 改变服务器的状态,与启动过程相同。