六、Elasticsearch master 节点是怎么选举的

一、首先来了解两个概念

1、一种比较简单的算法就是Bully,它通过一定的直接给每个节点赋予一唯一的ID,这些ID是可以排序的,每次master选举都会选举ID最大的节点。这种实现非常简单。但是会存在一些问题,在master负载过重时它会假死,于是第二大节点就成为了master节点。因此假死master节点因负载减轻又活了过来,于是他又被选为master,然后又假死……,这种情况可能一直存在导致系统不稳定。

2、集群还有一个问题就是脑裂(brain split):一个集群因为网络问题导致多个master选举出来而分裂。这也是master选举必须要解决的问题。

二、elasticsearch的master选举原理(它是在bully的基础上做了改进,它原理如下:)

(1)对所有可以成为master的节点根据nodeId排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
(2)如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举。
(3)对于brain split问题,需要把候选master节点最小值设置为可以成为master节点数n/2+1(quorum )

三、master 选举的内部实现方法:

1、按nodeId排序,直接返回第一个

public DiscoveryNode electMaster(Iterable nodes) {
            List sortedNodes = sortedMasterNodes(nodes);
            if (sortedNodes == null || sortedNodes.isEmpty()) {
                return null;
            }
            return sortedNodes.get(0);
        }

上面就是选举master的方法,可以看到,它的做法就是对候选节点排序然后直接将第一个返回。当然这只是上面所说的第一条。其实只有这个是不能够保证maser选举顺利的;

2、下面是“节点排序比较器”,它只是比较了nodeId,因此是按nodeId排序;

    private static class NodeComparator implements Comparator {

        @Override
        public int compare(DiscoveryNode o1, DiscoveryNode o2) {
            if (o1.masterNode() && !o2.masterNode()) {
                return -1;
            }
            if (!o1.masterNode() && o2.masterNode()) {
                return 1;
            }
            return o1.id().compareTo(o2.id());
        }
    }

但是:方法一和方法二都解决不brain split问题;为了解决brain split问题开发者加入了master候选数据量限制

3、解决脑裂为题

当集群master候选数量不小于3个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodes : n/2 +1:在ES配置文件elasticsearch.yml里设置)超过所有候选节点一半以上来解决脑裂问题;

public boolean hasEnoughMasterNodes(Iterable nodes) {
        if (minimumMasterNodes < 1) {
            return true;
        }
        int count = 0;
        for (DiscoveryNode node : nodes) {
            if (node.masterNode()) {
                count++;
            }
        }
        return count >= minimumMasterNodes;
    }

 

你可能感兴趣的:(elasticsearch,入门到实战)