系列文章目录
认识 Zookeeper -基本概念,组成和功能_小王师傅66的博客-CSDN博客
前言
上一篇文章中,我们简单的介绍了zookeeper产生的背景,数据模型中的4种znode,可以实现的功能等。接下来,在这篇文章中,我们将介绍zookeeper的集群以及选举机制。
一、zookeeper集群
为了保证zookeeper系统能提供更多的客户端连接,zookeeper提供了集群模式。zookeeper集群模式,实现了读写分离功能,提高了负载能力,支持更多的客户端连接;实现了主从自动切换,部分节点故障不会影响整个服务集群,使系统高可用。
1、角色说明
zookeeper 集群中总共有三种角色,分别是leader(主节点)follower(子节点) observer(次级子节点)
角色 |
描述 |
主要工作 |
leader |
主节点,领导者 是整个zookeeper集群工作机制中的核心。 |
1、事务请求的唯一调度和处理者,保证集群事务处理的顺序性; 2、集群内部各服务器的调度者; |
follower |
子节点,追随者 |
1、处理客户端非事务请求,转发事务请求给Leader服务器; 2、参与事务请求Proposal的投票; 3、参与Leader选举投票; |
observer |
次级子节点,观察者。 |
1、只处理客户端的非事务请求,转发事务请求给Leader服务器;通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力; 2、不参与事务请求Proposal的投票; 3、不参与Leader选举投票; |
事务请求:读以外的其他请求。增加,更新,删除节点请求;
2、选举机制
2.1 选举触发时机:
当集群中的服务器出现以下两种情况时会进行Leader的选举
服务器启动时;
服务器运行时,半数以上的节点无法和Leader建立连接
当节点初始起动时会在集群中寻找Leader节点,如果找到则与Leader建立连接,其自身状态变为follower或observer。如果没有找到Leader,当前节点状态将变化LOOKING,进入选举流程。
在服务器运行期间,follower或observer节点宕机只要不超过半数并不会影响整个集群服务的正常运行。但如果leader宕机,将暂停对外服务,所有follower将进入LOOKING 状态,进入选举流程。
2.2 选举前提:
1、Zookeeper 服务器处于 LOOKING 竞选状态
此时说明 Zookeeper 服务器集群处于群龙无首状态,另外,观察者状态不能参与竞选投票。
2、Zookeeper 集群规模至少要2台机器
集群规则为:2N + 1台,N > 0,即最少需要 3 台。因为 ZK 集群的机制是只要超过半数的节点正常,集群就能正常提供服务。只有在 ZK 节点挂得太多,只剩一半或不到一半节点能工作时,集群才会失效。
2.3 术语解释:
myid:服务器ID
在集群模式下,集群中的每台机器都需要感知到整个集群由哪几台机器组成,在配置文件中,可以按照这样的格式进行配置,每一行都代表一个机器配置:
server.id=host:port:port
其中,id被称为ServerID,用来标识该机器在集群中的机器序号。同时,在每台ZooKeeper机器上,.我们都需要在数据目录(即dataDir参数指定的那个目录)下创建一个myid 文件,该文件只有一行内容,并且是一个数字,即对应于每台机器的Server ID数字。myid就是每台机器的serviceID.
ZXID:事务ID
用来唯一标识一次服务器状态的变更。在某一个时刻,集群中每台机器的ZXID值不一定全都一致,这和ZooKeeper服务器对于客户端“更新请求”的处理逻辑有关。
2.4 选举流程
服务器启动时期的Leader选举
以3台机器组成的集群为例。服务器集群初始化阶段,当有一台服务器(我们假设这台机器的myid为1,因此称其为Serverl)启动的时候,它是无法完成Leader选举的。当第二台机器(同样,我们假设这台服务器的myid为2,称其为Server2)也启动后,此时这两台机器已经能够进行互相通信,每台机器都试图找到一个Leader,于是便进入了Leader选举流程。
1.每个Server会发出一个投票
由于是初始情况,因此对于Serverl和Server2来说,都会将自己作为Leader服务器来进行投票。每次投票包含的最基本的元素包括:所推举的服务器的myid 和ZXID,我们以(myid, ZXID)的形式来表示,即Serverl的投票为(1, 0),Server2 的投票为(2,0),然后各自将这个投票发给集群中其他所有机器。
2.接收来自各个服务器的投票。
每个服务器都会接收来自其他服务器的投票。集群中的每个服务器在接收到投票后,首先会判断该投票的有效性,包括检查是否是本轮投票、是否来自LOOKING状态的服务器。
3.处理投票。
在接收到来自其他服务器的投票后,针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK的规则如下:
1)优先检查ZXID。ZXID比较大的服务器优先作为Leader。
2)如果ZXID相同的话,那么就比较myid。myid 比较大的服务器作为Leader服务器。
现在我们来看Serverl和Server2实际是如何进行投票处理的。对于Serverl来说,它自己的投票是(1, 0), 而接收到的投票为(2, 0)。
首先,会对比两者的ZXID,因为都是0,所以无法决定谁是Leader;
接下来,会对比两者的myid,很显然,Server1发现接收到的投票中的myid是2,大于自己,于是就会更新自己的投票为(2, 0)。然后,重新将投票发出去。
对于Server2来说,不需要更新自己的投票信息,只是再一次向集群中所有机器发出上一次投票信息即可。
4.统计投票。
每次投票后,服务器都会统计所有投票,判断是否已经有过半的机器接收到相同的投票信息。对于Server1和Server2服务器来说,都统计出集群中已经有两台机器接受了(2,0)这个投票信息。
这里我们需要对“过半”的概念做一个简单的介绍。所谓“过半”就是指大于集群机器数量的一半,即大于或等于(n/2+1)。对于这里由3台机器构成的集群,大于等于2台即为达到“过半”要求。那么,当Serverl和Server2都收到相同的投票信息(2, 0)的时候,即认为已经选出Leader。
5.改变服务器状态。
一旦确定了Leader,每个服务器就会更新自己的状态;如果是Follower,那么就变更为FOLLOWING,如果是Leader,那么就变成LEADING。
服务器运行期间的Leader选举
在ZooKeeper集群正常运行过程中,一旦选出一个 Leader,那么所有服务器的集群角色一般不会再发生变化。也就是说, Leader 服务器将一直作为集群的Leader,即使集群中有非Leader集群挂了或是有新机器加入集群也不会影响Leader。但是一旦Leader所在的机器了,那么整个集群将暂时无法对外服务,而是进入新一轮的 Leader选举。
服务器运行期间的Leader选举和启动时期的Leader选举基本过程是一致的。我们假设当前正在运行的ZooKeeper服务器由3台机器组成,分别是Server1、Server2和Server3,当前的Leader是Server2。假设在某一个瞬间,Leader 挂了,这个时候便开始了Leader选举。
1.变更状态。
当Leader挂了之后,余下的非Observer服务器都会将自己的服务器状态变更为LOOKING,然后开始进人Leader选举流程。
2.每个Server会发出一个投票。
在这个过程中,需要生成投票信息(myid, ZXID)。因为是运行期间,因此每个服务器上的ZXID可能不同,我们假定Server1的ZXID为123,而Server3的ZXID为122。在第一轮投票中,Serverl 和Server3都会投自己,即分别产生投票(1,123)和(3,122),然后各自将这个投票发给集群中所有机器。
3.接收来自各个服务器的投票。
4.处理投票。
对于投票的处理,和上面提到的服务器启动期间的处理规则是一致的。在这个例子里面,由于Server1的ZXID为123, Server3的ZXID为122,那么显然,Server1会成为Leader。
5.统计投票。
6.改变服务器状态。
总结
通常哪台服务器上的数据越新,那么越有可能成为Leader。因为数据越新,它的ZXID 也就越大,也就越能够保证数据的恢复。如果集群中有几个服务器有相同的ZXID,那么SID较大的那台服务器成为Leader。
参考:
《从Paxos到zookeeper原理与实战》
zookeeper-选举流程_乱糟的博客-CSDN博客_zookeeper 重新选举