从人类选举开始讲
情况1:对候选人很熟悉,知道在候选人当中谁的能力最强,将票投给最强的那位
情况2:对候选人不熟悉,那么自己就是最强的,首先将票投给自己,但是在选举的过程中,发现了有别的候选人更强,于是退位让贤,修改投票,投给最强的那位
当所有人投完票后,票数最多的那位当选。
在这个场景有几个值得注意的点:
候选人能力:投票的基本原则是选出最强的那位
遇强改投:当遇到更强的人可以更改投票
投票箱:所有的票都在这里
领导者:票数最多的人会当选
zookeeper的选举机制
zk的选举和人类的选举类似,以人类选举的四个概念来理解一下
个人能力:在zk中,个人能力是由一个叫作事务ID来决定的,这个ID越大,说明这个节点的数据最新,也就能说明能力越强
遇强改投:每个节点初始都会投自己,然后将投票结果传给别的节点,当节点收到别人投票时发现别人的事务ID更大,此时会更改自己的投票并同步
投票箱:与人类选举不同的是,每个节点都会维护一个投票箱,并及时更新
领导者:当某个节点获得了超过半数的票数,那么这个节点就是领导者,投票也会随之结束
什么场景下zookeeper需要选举?
服务器初始化时:
假设现在有五个节点,编号从1到5
节点1启动时,发起一次选举,投自己一票,状态保持为LOOKING
节点2启动时,发起一次选举,投自己一票,此时节点1收到节点2的投票并发现节点2的ID比自己大,于是修改投票节点2,节点1和节点2状态保持为LOOKING
节点3启动时,发起一次选举,节点1、2、3先投自己一票,然后因为节点3的id最大,两者更改选票投给为节点3,此时节点3票数最多,当选leader,节点1和节点2更改状态FOLLOWING,节点3更改状态为LEADING
节点4启动时,发起一次选举,由于节点3已经当选了leader,节点4只有一票,于是落选,更改状态为FOLLOWING
节点5的启动同节点4
最终的结果就是节点3担任了leader。
运行时期的leader选举:
当leader节点挂了,那么整个 Zookeeper 集群将暂停对外服务,会触发新一轮的选举。
假设节点3宕机了,节点1的事务ID为99,节点2的事务ID为103,节点4的事务ID为100,节点5的事务ID为101,
运行期选举与初始状态投票过程基本类似,大致可以分为以下几个步骤:
状态变更。leader 故障后,余下的非 Observer 服务器都会将自己的服务器状态变更为LOOKING,然后开始进入leader选举过程
每个节点会发出投票
接收来自各个服务器的投票,如果其他服务器的数据比自己的新会改投票
处理和统计投票,没一轮投票结束后都会统计投票,超过半数即可当选
改变服务器的状态,宣布当选
选举中的核心概念
Server id(或sid):服务器ID
比如有三台服务器,编号分别是1,2,3。编号越大在选择算法中的权重越大,比如初始化启动时就是根据服务器ID进行比较。
Zxid:事务ID
服务器中存放的数据的事务ID,值越大说明数据越新,在选举算法中数据越新权重越大。
Epoch:逻辑时钟
也叫投票的次数,同一轮投票过程中的逻辑时钟值是相同的,每投完一次票这个数据就会增加。
Server状态:选举状态
LOOKING,竞选状态。
FOLLOWING,随从状态,同步leader状态,参与投票。
OBSERVING,观察状态,同步leader状态,不参与投票。
LEADING,领导者状态。