0
点赞
收藏
分享

微信扫一扫

ZooKeeper集群Leader选举理论解读(初次选举和故障恢复)



文章目录


  • 一、前言
  • 二、基本概念
  • 1、服务器角色
  • 2、票据ZXID和myid
  • (1)ZXID
  • (1)myid
  • 三、Leader选举
  • 1、集群第一次启动Leader选举
  • 2、集群运行期间Leader选举
  • (1)Leader故障的几种典型场景
  • (2)故障恢复
  • 3、Observer旁观者的好处
  • 四、要点总结
  • 五、参考资料


一、前言

​ZooKeeper​​​ 参考 ​​Paxos​​​算法,专门设计了一种支持崩溃恢复的原子广播协议 ​​Zab​​​(​​Zookeeper Atomic Broadcast​​​),​​Leader​​​选举是其核心思想,也是保证​​ZooKeeper​​数据一致性的关键所在。

ZooKeeper集群Leader选举理论解读(初次选举和故障恢复)_数据

二、基本概念

1、服务器角色

一个正常运行的zk集群中,一定存在两种服务器角色 ​​Leader​​​ 和 ​​Follower​​​,​​Leader​​​负责事务请求处理协调和数据同步以保证数据顺序最终一致性;​​Follower​​​具有投票,只读请求可以自己处理,但是事务请求需要转发给​​Leader​​​。还有一种角色 ​​Observer​​​,和 ​​Follower​​​ 统称为 ​​Learner​​,但是没有投票权,也不参与过半数机制。

2、票据ZXID和myid

在进行​​Leader​​​选举时,​​ZXID​​​和​​myid​​​作为投票依据,比较服务之间​​ZXID​​​和​​myid​​​的大小来判定票投给谁,最终得票过半数的成为​​Leader​​。

(1)ZXID

​ZXID​​​ 是事务ID,由​​Leader​​​生成,是一个16进制的递增数字,共64位(二进制),由两部分组成:高32位代表当前​​Leader​​​任期编号,每进行一次​​Leader​​选举就加一;低32位是事务计数器,递增,整体上是递增的。

​ZXID​​ 的作用主要有两个:


  • 保证数据的顺序一致性,所有事务请求统一由​​Leader​​​发起提议,严格按​​ZXID​​顺序执行,当前事务请求没有处理完,再来新的事务请求就会阻塞。
  • ​ZXID​​ 参与选票依据,​​ZXID​​大的获得选票​。

ZooKeeper集群Leader选举理论解读(初次选举和故障恢复)_Leader选举_02

(1)myid

​myid​​​应该比较眼熟吧,在搭建zk集群时,每个服务节点的 ​​dataDir​​​ 目录下都会创建一个​​myid​​​文件,文件中只包含一个数字,且不能重复;在​​zoo.cfg​​​配置里也可以看到有几行​​server.A=B:C:D​​​,A代表的就是​​myid​​。

​myid​​​作为​​zk​​​服务的​​ServerId​​​,简称​​SID​​​,并且也是选票依据,当​​ZXID​​​相等时,​​myid​​大的获得选票。

三、Leader选举

1、集群第一次启动Leader选举

因为3个服务节点的zk集群​​Leader​​​选举可能过于简单,所以下面以5个服务节点组成的zk集群来看看​​Leader​​选举的过程。

第一次启动,都处于初始状态,​​ZXID​​​都是0,​​myid​​​分别为1、2、3、4、5。票据​​(ZXID,myid)​​​分别为​​(0,1)​​​、​​(0,2)​​​、​​(0,3)​​​、​​(0,4)​​​、​​(0,5)​​(此概念不涉及源码层面,但是原理上差不多),如下是具体的投票选举过程:


  • ​myid=1​​ 的服务器启动,发起一次投票,服务器1给自己投1票,票数不过半,选举无法完成。
  • ​myid=2​​ 的服务器启动,再发起一次投票,服务器1和服务器2分别给自己投一票。
  • 服务器1和服务器2交换选票信息,先比较​​ZXID​​​,都是0,再 比较​​myid​​​,服务器2的 ​​myid​​​ 比服务器1大,所以服务器1的票据更改为​​(0,2)​​,服务器2不需要更改。
  • 统计选票,服务器1和服务器2变更选票信息后再次交换选票,服务器1和服务器2都有两张一样的票​​(0,2)​​,意为服务器2有两票,但是票数不过半,无法完成投票。
  • ​myid=3​​​ 的服务器启动,发起投票,此时服务器1和2持有的票据都是​​(0,2)​​​,服务器3的票据为​​(0,3)​​​,互相交换选票(每个服务器的票据都要广播给其他具有投票权的服务器),服务器3的 ​​myid​​​ 比服务器2的 大,服务器1和2变更票据为​​(0,3)​​,服务器3保持不变。
  • 再次统计选票,服务器3有三张票,服务器1和2都是零票。服务器3持有的票数过半,​​Leader​​​选举完成,服务器3成为 ​​Leader​​​,服务器1和2成为​​Follower​​。
  • ​myid=4​​​的服务器启动,发现集群中已经有​​Leader​​​了,就变更自己的角色状态为​​Follower​​。
  • ​myid=5​​​ 的服务器启动,同理也变更自己的角色状态为 ​​Follower​​。

过程还是比较简单,也很容易理解,对投票过程总结3点:


  • 交换选票​,每个服务器将自己持有的票据广播给其他具有投票权的服务器。
  • 变更选票​​,票据比较,所有服务器都将自己的选票信息更新为那个​​ZXID​​​最大的或者​​myid​​最大的服务器的选票,这就相当于投票了。
  • 统计选票​​,每个服务器再广播一次自己持有的票据,每个服务器判断自己接收到的相同票据数量是否过半数,是就推选该票据的​​myid​​​对应的服务器成为​​Leader​​​,其他都为​​Follower​​。

如下图是伪集群服务器数量3的第一次启动过程演示:

ZooKeeper集群Leader选举理论解读(初次选举和故障恢复)_Leader选举_03

2、集群运行期间Leader选举

zk集群正常运行期间,一旦选出了Leader,那么所有服务器的角色都不会再发生变化。后启动的服务器发现有​​Leader​​​,就直接变更自己的角色为​​Follower​​​;​​Follower​​挂了,只要正常运行的服务器数量还在半数以上,整个集群就还可以正常对外提供服务。

但是一旦​​Leader​​​所在的服务器挂了,如果集群中正常运行的机器半数以上,就得重选​​Leader​​。

(1)Leader故障的几种典型场景

​Leader​​​在挂掉的时候,可能还有一些写操作没有完成,可能会造成剩下的服务器数据不一致。如下是几种​​Leader​​故障的场景:


  • ​Leader​​​完成了所有事务​​COMMIT​​​,然后挂了,此时过半数以上的服务器的数据是一致的,重选​​Leader​​基本不影响。
  • ​Leader​​​在接收到事务请求至最后广播​​COMMIT​​​之前的某个时刻挂了,这都属于未完成的事务请求,即使有服务器已经把事务请求持久化到了日志文件,但是还没有完成最后的​​COMMIT​​将数据同步到内存数据库。未完成的事务会被丢弃。
  • ​Leader​​​在广播​​COMMIT​​​的过程中挂了,这就导致某些收到了​​COMMIT​​完成了事务,有些没收到,还处于持久化事务日志文件的阶段,最终导致数据不一致。

(2)故障恢复

故障恢复包括两部分:​​Leader​​ 选举和数据恢复。

​Leader​​ 重新选举的过程和第一次启动选举一样,不再赘述。成为新Leader必须满足以下两个条件:


  • 新​​Leader​​​的​​ZXID​​是所有服务器中最大的,这就可以最大限度的恢复数据。
  • 新​​Leader​​​不能包含未​​COMMIT​​的事务提议,如果事务日志文件中有未同步到内存数据库的事务将会回滚丢弃。

新Leader选举出来以后,就开始恢复数据了。为了集群全局数据一致性,所有的 ​​Follower​​上的数据都必须和Leader的一样:


  • ​Leader​​​有的​​Follower​​​没有,​​Leader​​​将这些事务同步给​​Follower​​。
  • ​Leader​​​没有的,​​Follower​​​有,​​Follower​​需要回滚丢弃这些所谓超前的事务。

注:如果原先集群运行了一段时间,产生了数据不一致,然后全部停机后,再一个个重启,最好是先去看看每个服务的事务日志文件内记录的最后提交的​​ZXID​​​,最大的那个服务先重启,否则可能会导致​​Leader​​已经选举好了,后面一个带着最全数据的服务节点重启了,反而要回滚事务。

需要注意的是在Leader选举的过程中,集群是处于无法正常对外提供服务的状态。

3、Observer旁观者的好处

在​​Leader​​​选举的过程中一直没有说​​Observer​​​,原因是​​Observer​​​没有投票权,但是它除了没有投票权,不参与过半机制外,和​​Follower​​​差不多,也可以通过客户端连接,也可以从​​Leader​​同步数据。

​Observer​​的机制可以应用在扩容上,不仅可以实现数据的动态迁移和扩容,还可以就只作为一个与世无争的旁观者,不影响集群的正常写性能,还提升读性能,可以用在异地机房数据同步。

ZooKeeper集群Leader选举理论解读(初次选举和故障恢复)_原力计划_04

四、要点总结

熟悉 ​​Leader​​​ 选举的底层理论,可以很好的应对集群的迁移和扩缩容。​​ZooKeeper​​​ 在Leader选举期间和正常服务个数不过半数都无法对外提供服务,并且会丢弃一些未完成的事务,以保证数据一致,所以它是​​CP​​​,即保证数据一致性(​​Consistency​​​)和分区容错性(​​Partition Tolerance​​​),但不保证可用性(​​Available​​)。

本篇要点总结如下:


  1. ​Leader​​​选举,先比较​​ZXID​​​,​​ZXID​​​较大的获得更多选票,​​ZXID​​​相等,比较​​myid​​​,​​myid​​较大的获得更多选票。
  2. 票数过半即可选出​​Leader​​​,后来者则自动成为​​Follower​​。
  3. 故障恢复,​​Leader​​重选,会丢弃未完成的事务。
  4. ​Observer​​​ 虽然没有投票权,也不决定过半机制,但是同样可以和 ​​Leader​​ 建立连接,同步数据。这一特点可以用于异地机房同步数据和扩容上,极大提升读性能但对写性能影响极小。

五、参考资料


  1. 书籍:《从Paxos到Zookeeper分布式一致性原理与实践》
    1. https://www.bilibili.com/video/BV1to4y1C7gw
  2. Migrating Kafka’s Zookeeper With No Downtime

如若文章有错误理解,欢迎批评指正,同时非常期待你的评论、点赞和收藏。

如果想了解更多优质文章,和我更密切的学习交流,请关注如下​同名公众号【徐同学呀】​,期待你的加入。

注:《ZooKeeper-分布式过程协同技术详解》和 《从Paxos到Zookeeper分布式一致性原理与实践》pdf版本由于版权问题有需要这两本PDF的请关注公众号:徐同学呀,回复zkpdf获取。

ZooKeeper集群Leader选举理论解读(初次选举和故障恢复)_服务器_05



举报

相关推荐

0 条评论