Elasticsearch的任意一个节点都可以设置node.master和node.data属性,该属性的意义如下表所示

master \ data
true false
true 既是Master Eligible,又是data节点 单纯的Master Eligible节点
false 单纯的data节点 纯粹的Coordinating Node,协调节点负责查询时的数据收集、合并以及聚合等操作,ES中所有节点都是协调节点

来自于流行病的Gossip协议一文中我们已经知道了Elasticsearch中所有的节点是如何组成为一个集群的,接下来我们了解ES集群中是如何选出master的。

选举的基本原则

ES针对当前集群中所有的Master Eligible Node进行选举得到master节点,为了避免出现Split-brain现象,ES选择了分布式系统常见的quorum(多数派)思想,也就是只有获得了超过半数选票的节点才能成为master。在ES中使用 discovery.zen.minimum_master_nodes 属性设置quorum,这个属性一般设置为 eligibleNodesNum / 2 + 1

如何触发一次选举

当满足如下条件是,集群内就会发生一次master选举

  1. 当前master eligible节点不是master
  2. 当前master eligible节点与其它的节点通信无法发现master
  3. 集群中无法连接到master的master eligible节点数量已达到 discovery.zen.minimum_master_nodes 所设定的值

如何选举

当某个节点决定要进行一次选举是,它会实现如下操作

  1. 寻找clusterStateVersion比自己高的master eligible的节点,向其发送选票
  2. 如果clusterStatrVersion一样,则计算自己能找到的master eligible节点(包括自己)中节点id最小的一个节点,向该节点发送选举投票
  3. 如果一个节点收到足够多的投票(即 minimum_master_nodes 的设置),并且它也向自己投票了,那么该节点成为master开始发布集群状态

下面我们用一个实际的例子来解释选举流程,假设有node_a和node_b,node_a向node_b发送选票。

  • 如果node_b已经是master,则node_b就把node_a加入集群,之后node_b发布最新的集群状态,此时node_a会被包含在最新的集群状态里面。
  • 如果node_b正在进行选举,则node_b会把这次投票记录下来,之后node_b可能成为master或者继续等待选票。node_a等待node_b发送最新的集群状态或者超时触发下一次投票。
  • 如果node_b认为自己不会成为master,则拒绝这次投票,node_a将触发下一次投票。

其它的选举办法

Zookeeper

事实上ES可以使用Zookeeper来进行master选举,方法如下

  • 所有master eligible尝试在zk上创建指定路径
  • 只有第一个节点能创建成功,该节点成为master,其余节点watch此路径
  • 一旦zk失去master的连接,该路径被删除,其余master eligible继续尝试创建路径,同样只能有一个节点成功创建并成为master
  • 重复以上步骤

Zookeeper来实现选主可以使得ES内部的选举算法变得非常的简单,至于为什么ES要自己发明一套轮子就不是很清楚了。

Raft

ES本身的选举算法在早期还是比较粗糙的,这些年来也在不断改进中。Raft算法本身经过严格的论证,是一种非常优秀的一致性算法,至于ES没有选择使用Raft而是自己发明了一套选举算法的原因则很简单,因为ES早期版本的时候Raft算法还没有被提出来,不过我认为随着ES的发展应该会更多的参考这些已经经过严格论证的选举算法。

Raft作为一种分布式一致性协议,其本身不止描述了选举过程,还提供了日志同步安全性的相关行为的描述。

参考

ElasticSearch 内部机制浅析(一)
Master Election
Leader Election, Why Should I Care?
Elasticsearch分布式一致性原理剖析(一)-节点篇
ELASTICSEARCH 选主流程