Curator框架中的Leader选举细节说明
之前写过一篇文章,讲了下如何基于Zookeeper和Curator框架写Master选举的Demo,本文来细说下Curator框架在进行Master选举的时候,内部是如何实现的。
Demo可以查看之前写的那篇文章《一个简单的基于Zookeeper实现主从选举的例子》。
客户端调用LeaderClient.start()方法开始进行Master选举,start()方法内部会执行internalStart()方法:
reset()方法就是Master选举的核心,方法内部分成了两个步骤:
1.在Master选举的ZK路径下创建EPHEMERAL_SEQUENTIAL(临时有序节点)
client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).inBackground(callback).forPath(ZKPaths.makePath(latchPath, LOCK_NAME), LeaderSelector.getIdBytes(id));
临时有序节点命名格式为PROTECTED_PREFIX+UUID+LOCK_NAME+编号,例如有两个节点进行Master选举,它们的名字分别如下:
_c_8c79d7bc-9ef2-43f8-a0d2-b136f51a9a16-latch-0000000049
_c_b4e6bdef-052e-448c-aaaf-de157c982f01-latch-0000000048
2.节点创建完毕之后,回调执行callback方法,内部会执行getChildren():
该方法内部调用checkLeadership()方法:
checkLeadership()方法会对Master选举路径下的节点进行排序,对于index为0的标记为leader(即编号最小的会被当成leader);对于index大于0的则添加watch,watch的路径为前一个节点;如果前一个节点被删除了(Event.EventType.NodeDeleted),则重新触发getChildren()方法。
这个方法随后还注册一个callback,如果前一个节点被删除,则重新触发reset()操作:
不太明白这里是为啥了...因为前面不是已经注册过watch了么…望知道的大神帮忙解释一下
LeaderLatch内部还使用了ConnectionStateListener对自身节点变化进行相应处理:
handleStateChange(newState)中对不同的Session状态进行的处理如下:
可以看出,各种情况考虑的确实很到位啊!!!
个人也得出了如下结论:
如果在运行的时候Master进程如果被kill掉了,那么就一定会发生主备切换。因为原Master进程启动之后,这个新的进程在Master选举的ZK路径下创建的肯定是一个新的节点。
拿上篇文章中写的那个Demo程序验证了下,发现确实是这样的。