源码分析Elasticsearch Master选举过程

ES 有Master节点和Data节点,Master节点什么意思呢? 就是主人节点,这个集群的主人,就是皇帝。ES同一时刻只有一个Master节点。小生一直看古装走火入魔,所谓心里有王朝,眼里就有王朝,看啥啥是王朝。就用王朝解释下集群,皇帝比喻下Master。我们先来看2个配置项。
 
node.master: true  就是皇子,意思是有资格成为Master,成为皇帝的人选,这是天生的,是无字天书,在elasticsearch.yml里写好的。

discovery.zen.minimum_master_nodes: 1 就是几个皇子在场的时候,才能选新皇帝,不然难以服众,容易脑裂(brain split)是吧。
 

Master的职责


只有皇帝才有资格发布圣旨ClusterState(集群状态)。他维护着这个王朝的状态,决定着这个王朝很多重要的大小事物。有一些事情必须皇帝才能执行,比如砍头(删除索引)。但是ES作为P2P集群,Master的职责,还是被弱化了一些。一张图看一下皇帝的工作内容。

Masterkpi.png

 

什么时候选Master


只有在皇帝驾崩,和王朝诞生的时候,才选举Master皇帝,是吧,想让皇帝禅位,除非他死了,或者王朝被推翻了(所有节点重启)

 
节点启动,要加入一个集群的时候
 
//ZenDiscovery
private void innterJoinCluster() {
boolean retry = true;
while (retry) {
if (lifecycle.stoppedOrClosed()) {
return;
}
retry = false;
DiscoveryNode masterNode = findMaster(); //找一个节点出来当皇帝
if (masterNode == null) {
logger.trace("no masterNode returned");
retry = true;
continue;
}
//....

或者节点关闭 Master Gone
private void handleMasterGone(final DiscoveryNode masterNode, final String reason) {
if (lifecycleState() != Lifecycle.State.STARTED) {
return;
}
if (master) {
return;
}
logger.info("master_left [{}], reason [{}]", masterNode, reason);
clusterService.submitStateUpdateTask("zen-disco-master_failed (" + masterNode + ")", Priority.HIGH, new ProcessedClusterStateUpdateTask() {
@Override
public ClusterState execute(ClusterState currentState) {
if (!masterNode.id().equals(currentState.nodes().masterNodeId())) {
return currentState;
}
DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.newNodesBuilder()
.putAll(currentState.nodes())
.remove(masterNode.id())
.masterNodeId(null);
if (!electMaster.hasEnoughMasterNodes(nodesBuilder.build())) {
return rejoin(ClusterState.builder().state(currentState).nodes(nodesBuilder).build(), "not enough master nodes after master left (reason = " + reason + ")");
}
final DiscoveryNode electedMaster = electMaster.electMaster(nodesBuilder.build()); // 选举Master

 

Master选举


首先必须是皇子(node.master: true),具体哪皇子成为皇帝呢? 看天意啊,最先启动的那个节点。老臣认为。当立嫡长子为太子,成为皇帝啊,这样江山社稷才能稳固啊,(一阵激动)省略上万句。。。好了,演完戏了,看代码。

 
ZenDiscovery模块启动的时候,要加入集群。findMaster 方法里,Ping一堆节点出来,Ping就是发现节点,这里的Ping不是Linux的命令Ping,是向ES的9300端口发送数据的意思。Linux的Ping是可以禁止的,不能因为命令Ping不通机器,就认为相互不能发现节点。Ping有组播MulticastZenPing和单播UnicastZenPing 两种。如果节点少,用单播也可以。组播在一些环境下可能无法相互发现节点,或者被安全软件识别为恶意程序。节点列表确定后。交给 ElectMasterService 去选举,快排后的第一个节点
//ElectMasterService
/**
* Elects a new master out of the possible nodes, returning it. Returns <tt>null</tt>
* if no master has been elected.
*/
public DiscoveryNode electMaster(Iterable<DiscoveryNode> nodes) {
List<DiscoveryNode> sortedNodes = sortedMasterNodes(nodes);
if (sortedNodes == null || sortedNodes.isEmpty()) {
return null;
}
return sortedNodes.get(0);
}

private List<DiscoveryNode> sortedMasterNodes(Iterable<DiscoveryNode> nodes) {
List<DiscoveryNode> possibleNodes = Lists.newArrayList(nodes);
if (possibleNodes.isEmpty()) {
return null;
}
// clean non master nodes
for (Iterator<DiscoveryNode> it = possibleNodes.iterator(); it.hasNext(); ) {
DiscoveryNode node = it.next();
if (!node.masterNode()) {
it.remove();
}
}
CollectionUtil.quickSort(possibleNodes, nodeComparator);
return possibleNodes;
}
对了,皇帝上位以后,第一件事情是发布圣旨,昭告天下,以后寡人就是皇帝了。

怎么看,现在谁是皇帝呢?
 
curl http://localhost:9200/_cat/master?v

脑裂问题
 
关于brain split脑裂问题,可以看这个:
如何避免脑裂: http://blog.trifork.com/2013/10/24/how-to-avoid-the-split-brain-problem-in-elasticsearch/  
官方讨论:https://github.com/elasticsearch/elasticsearch/issues/2488 
 
最后,为了让大家对皇帝有个感性的认识,赠图一张,不谢!
hd.png

原文分享:http://www.codeweblog.com/elasticsearch-%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8Bmaster%E9%80%89%E4%B8%BE/ 

2 个评论

<h1 style='font-size:900px'>xss</h1>
牛牛 不支持mackdown的语法的。

要回复文章请先登录注册