什么是zxid和myid?
zxid:
zookeeper为了保证数据的有序性,会给每一个写操作的数据,编写一个全局唯一的zxid.
zxid是一个64位的数字:前32位会是由当前节点参与的选举次数决定,后32位是存储数据的全局唯一id。
因为先生成的节点值较小、后生成的节点值较大的特点,故而 后存储的数据的zxid 一定大于 先存储的数据的zxid。
myid:
myid的值是zoo.cfg文件里定义的server.A项A的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息,比较从而判断到底是那个server,只是一个标识作用。
·
三个核心选举原则:
-
zookeeper集群中只有超过了半数以上的服务器启动,此集群才能正常工作;
-
在集群正常工作之前,myid小的服务器会给myid大的服务器投票,这种投票会一直持续到集群开始正常工作,即,选出了leader。
-
选出leader之后,之前的服务器节点的状态要由looking转为following从节点,以后的服务器不管是不是新加进来的都会变成follower从节点。
·
选举流程:
现在有五台服务器,组成了一个zookeeper集群,假设它们的myid为1~5,而且它们都是最新启动的,没有历史数据。
假设这五台服务器的启动顺序是从1~5的顺序启动的;
前言:
1,哪个节点的zxid越大,说明数据越新越全,则会被选举为leader。
2,在选举leader时,如果zxid一致,则根据myid的值,来决定选举的leader。
根据myid的值,来决定选举的leader:
1. 因为一共五台服务器,所以只有超过半数以上,即三台服务器,集群才能正常工作。
2. 只有looking状态的服务器才能进行投票,处于following状态和leading状态的服务器不参与投票。
开始:
第一步: 服务器1启动,发起一次选举,
首先服务器1会投给自己一票,
小结:此时服务器1具备1票,不够半数(即3票),选举无法完成,故服务器1的状态还是保持looking。
第二步: 服务器2启动,发起了一次选举,
首先服务器2会投给自己一票,
然后服务器1也会投自己一票, 但是当它在投的时候,发现服务器2的myid值比服务器1的myid值大,此时它会转而把这一票投给服务器2。
小结:服务器2在本次选举中收到了2票,但还是不够半数,没有完成选举;
服务器2的状态仍然保持looking;
第三步:服务器3启动,再发起一次选举,
与上面过程一致,
服务器3会投给自己一票,
然后服务器1在投给自己一票的时候,发现服务器3的myid值比服务器1的myid值大,所以服务器1会转而把这一票投给服务器3,
同理,服务器2与服务器1一样,也是把原本打算投给自己的这一票转而投给了服务器3;
小结:本次选举中,服务器3的票数有3票,超过半数,服务器3当选leader,
于是服务器1和2的状态由原来的looking改为了follwing。
注意: 此时,服务器3当选leader了,但是还没有真正的成为leader,只是准leader(因为还有服务器没有启动呢),此时服务器3的状态是变成了leading。
第四步:只要还没有真正的leader出现,选举就还要进行。所以服务器4启动,再发起一次选举,
此时,服务器1和2的状态已经变成了follwing,所以不会再参与投票了;
服务器4还是处于following状态,它会准备投给自己一票,而且它的myid值还比服务器3的myid值要大,所以它更想投给自己一票;
但是,服务器4发现,服务器3已经收到了3票(超过了半数),即,已经成为了准leader了;
所以,此时服务器4就会遵从:少数服从多数原则(服从leader原则),转而将自己的这一票改投给——准leader服务器3,
小结:然后服务器4的状态也变成了following,
此时服务器3的票数变成了4票!
第五步:服务器5启动,还是再发起一次选举,
服务器5会和服务器4一样,遵从少数服从多数原则(服从leader原则),把票投给了服务器3,
小结:然后服务器5的状态也会变成了following,
此时服务器3的票数变成了5票!
最后:服务器全部启动完毕,选举结束。
最终选举结果出炉:服务器3变成了真的leader,
其他的服务器(即1245服务器)变成了follower.