1. ZooKeeper 的工作原理
Zookeeper 的核心是Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。
为了保证事务的顺序一致性,Zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了 zxid, zxid 是一个 64位的数字,它的高 32 位是epoch, 用来表示 Leader 的任期,标识Leader关系是否改变,每当一个Leader被选出来时,它都会有一 个新的epoch, 表示进入新的 Leader 时期。Zxid的低 32 位用于递增计数,表示在当前 Leader 任期内的事务顺序,确保事务按全局顺序执行。
2.Leader 选举流程
当 Leader 失效时,ZooKeeper 会通过 Zab 协议(ZooKeeper Atomic Broadcast)选举新的 Leader。
Zookeeper 的选举算法有两种:一种是基于 basic paxos 实现的,另外一种是基于 fast paxos 算法实现的。系统默认的选举算法为fast paxos。
简单讲讲Basic Paxos 流程:
- 由发起选举的 Server 线程担任,负责统计投票结果并推荐 Leader。
- 选举线程向所有 Server(包括自己)发起询问。
- 选举线程收到回复后,验证回复是否是自己发起的询问(检查 zxid 是否一致),然后获取对方的 id(myid)并存储到当前询问对象列表中。最后获取对方提议的 Leader 信息(id, zxid),并存储到投票记录表中。
- 收到所有 Server 回复后,选举线程计算 zxid 最大的 Server。并将该 Server 设置为下一次投票的推荐 Leader。
- 如果某个 Server 获得超过半数(n/2 + 1)的票数,则成为 Leader。否则,继续选举流程,直到选出 Leader。
通过Basic Paxos 流程分析可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1(一般为3,5,7), 且存活的Server的数目不得少于n+1。每个Server启动后都会重复以上流程。
而Fast Paxos 流程是在选举过程中,某Server首先向所有Server提议自己要成为leader, 当其它Server收到提议以后,解决epoch和 zxid的冲突(依次比较epoch,zxid,myid的顺序,值较大的一方获得投票),并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
- Basic Paxos 强调一致性和容错性,适用于需要强一致性的场景。
- Fast Paxos 通过减少消息传递的轮次,快速选出一个 Leader。适用于需要快速选举 Leader 的分布式系统场景。
Q:选举时为什么按照这个顺序epoch > zxid > myid比较?
A: epoch 表示 Leader 的任期,是一个全局递增的编号,可以确保选举出的 Leader 是最新的,避免旧 Leader 重新当选。zxid 是事务 ID,表示 Server 处理的最新事务,zxid 更大的 Server 处理了更多的事务,拥有更完整的数据,减少数据同步的开销。myid 是 Server 的唯一标识,是一个静态配置的值,用于解决完全冲突的情况。选择 myid 更大的 Server 可以确保选举结果的唯一性。