Elasticsearch是如何选举出master的
2019-03-18
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选举
- 当前master eligible节点不是master
- 当前master eligible节点与其它的节点通信无法发现master
- 集群中无法连接到master的master eligible节点数量已达到
discovery.zen.minimum_master_nodes
所设定的值
如何选举
当某个节点决定要进行一次选举是,它会实现如下操作
- 寻找clusterStateVersion比自己高的master eligible的节点,向其发送选票
- 如果clusterStatrVersion一样,则计算自己能找到的master eligible节点(包括自己)中节点id最小的一个节点,向该节点发送选举投票
- 如果一个节点收到足够多的投票(即
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作为一种分布式一致性协议,其本身不止描述了选举过程,还提供了日志同步与安全性的相关行为的描述。