1、zookeeper集群角色

2、zookeeper事物操作

3、zookeeper保证消息的有序性:

4、zab协议

5、zab协议和Paxos算法的联系与区别

1、zookeeper集群角色

        zookeeper集群中又叫主备模式,里面有三种角色,分别是Leader(领导者)、Follower(跟随者)、Observer(观察者)。

        Leader(领导者):是zookeeper集群的核心,事物请求的唯一调度者和执行者,保证请求的顺序执行。集群内部各个服务的调用者。

        Follower(跟随者):用来处理非事物请求,并将事物请求发送给领导者。参数事物的投票和选举的投票。

        Observer(观察者):用来处理非事务请求,并将事物请求发送给Leader。观察节点的最新数据并进行同步。与Follower的区别就是其不参与事物的投票和选举的投票。

2、zookeeper事物操作

        zookeeper的事物请求指的是修改数据的操作,而集群中所有事物操作全部是由领导者进行完成的,不管是跟随者还是观察者在接收到事物请求后都会转发到领导者上,由领导者统一进行操作。

        领导者会为集群中每一个跟随者建立一个FIFO(先进先出)队列。领导者在接收到事物请求后,会将该事物请求转化为一个事物提议(Proposal),并将该提议通过队列发送到集群上给所有的跟随者上。

        每个跟随者在接收到提议后都会进行回复领导者,当领导者接收到一半以上的跟随者的回复就会再次发送一个commit命令给所有的跟随者,告诉他们将上一个提议进行提交并写入到本地。

        当领导者接收到过半跟随者同步完成消息后,会进行同步数据,将数据同步到跟随者和观察者机器上。至此,整个事物请求操作完成。

        那在这个阶段会发生两个问题导致集群数据不一致。

        1、已经被处理的消息不能丢失。

                当领导者收到半数以上的跟随者的ack(回复)后,就会像集群中的跟随者发送commit命令。但是如果各个跟随者在收到commit命令前,领导者就挂了,导致剩下的服务器并没有执行到这个消息。举个例子:领导者发送commit命令后,跟随者1接收到了并写入自己的服务器,而跟随者2没有收到commit命令的时候领导者就挂了。此时跟随者1将事物成功消息发送给客户端了,那么这条被确认成功的消息就必须要同步到集群中所有的机器上。因为客户端已经收到了事物成功的消息,所以即便其他的跟随者没有收到commit命令,也必须想办法告诉其他跟随者这条消息保存成功。

        2、被丢弃的消息不能再次出现。

                当领导者接收到事物请求后,生成事物提议(Proposal)后就挂掉了,此时集群中的跟随者还没有接收到事物提议。当领导者挂掉以后会进行重新选举,那么新的领导者是不知道该提议的存在。那么此时为了保证集群中数据一致性,该提议必须被丢弃。也就是收该提议的事物操作必须是失败的。

        为了保证以上两个问题不会影响集群数据一致,所以zookeeper使用zab协议来保证数据的一致性。

3、zookeeper保证消息的有序性:

        zab协议必须要有一个选举算法来保证以上两个问题。那么zab协议的选举算法是怎样的呢?讲这个问题之前要先说一下zookeeper是如何保证消息的有序性的。

        领导者在接收到事物请求后,都会创建一个新的事物提议(Proposal),同时会为该提议生成一个全局唯一递增的事物id,也就是zxid。由于zab协议保证执行的顺序性,所以所有的事物都会根据zxid的大小来进行顺序执行。所以保证了集群事物的顺序性问题。

        而zxid是一个64位的数字,其高32位是epoch编号(zab协议通过epoch编号来区分Leader周期变化的策略),也就是通过epoch来判断当前谁是领导者,每次重新选举后epoch都会重新生成一个epoch(新的epoch = 旧的epoch+1)。该编号低32位是一个消息计数器,没接收到一条消息都会+1。

 4、zab协议

消息广播和崩溃恢复。zookeeper就是使用了这两种模式实现了分布式协调服务。是zookeeper集群中最重要的组成。 

消息广播:

        zab协议使用的消息广播模式类似于二阶段提交。相当于原子广播协议。针对事物请求生成一个事物提议,在将事物提议广播到所有跟随者上。一旦超过半数接收到并进行回复就相当于该集群全部接收到提议。在使用广播形式告诉所有跟随者进行提交。一旦接受到消息的跟随者不足一半时,领导者就会将该事物修改成失败。用来保证集群数据的一致性。

奔溃恢复:

        当领导者出现崩溃退出或服务宕机,又或者有一半以上的跟随者连不上领导者了。此时集群就会进入崩溃恢复模式。此时需要重新选举一个新的领导者。而领导者选举是根据zxid来进行选择的。最大的zxid会成为领导者。当领导者选举出来以后,会通知所有的跟随者,告诉他们谁是领导者,并进行数据同步。当超过半数的跟随者回复收到领导者确认的消息后,会自动退出奔溃回复模式,进入到消息广播模式进行消息同步。

解决上面两个问题:

        已经被处理的消息不能丢弃:

                因为zxid是根据每次操作由epoch和消息计数器组成的,也就是说,zxid越大越接近领导者的操作,新的领导者的zxid最后一个记录就是旧领导者最后一个操作。也就是说当就领导者发送commit命令后,跟跟随者1执行了commit,而其他的跟随者还没来得及接受到commit命令时,领导者就挂了。那么此时跟随者1的zxid最大。

        跟随者1也会变成新的领导者,那么跟随者1最后一条操作就是就领导者最后一次操作,所以当跟随者1变成领导者后,其数据就是最新数据,他会将自己的数据同步到其他跟随者上。所以就保存了消息不会被丢弃。

        被丢弃的消息不能再次出现:

                当领导者发送提议给跟随者后,领导者就挂掉了。说明当前事务提议并没有成功,即便跟随者接收到了事务提议,也没有接收到该事物提议的commit命令。所以新的领导者同步数据的时候只会同步自己已经commit的数据,而提议数据将会被直接丢弃。其他跟随者也会同步新的领导者。故提议数据会被丢掉。

5、zab协议和Paxos算法的联系与区别

        zab协议和Paxos算法大致是一样的,两者都存在类似于Leader角色,用来管理所有的Follower的运行。也都是等待超过半数的Follower给出正确反馈才进行事物提交。

两者的区别是zab协议中事物提议都有一个epoch,而Paxos算法里叫Ballot。还有就是zab是用来构建高可用的主备系统,而Paxos算法是用来构建分布式一致性状态机系统的

        zab协议和Paxos算法本质区别在于目的不同,他们的设计场景是不一样的。一个是高可用主备场景,一个是一致性状态机场景。