暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Elasticsearch集群master选举机制

xbaobao 2020-08-27
483

其代码主要是ZenDiscovery这个类,在它的innerJoinCluster()方法中,最主要的一部分代码就是

publicvoid innerJoinCluster() {

        //.......

        while (masterNode == null) {

             masterNode = findMaster();

        }

        //......

}

一直阻塞直到找到master节点

private DiscoveryNode findMaster() {

        // 连接其他节点,获取其他节点的信息

        ZenPing.PingResponse[] fullPingResponses                                                      =pingService.pingAndWait(pingTimeout);

        if (fullPingResponses == null) {

             returnnull;

        }

     

        //过滤所有响应节点, 排除掉client节点,单纯的data节点

        List<ZenPing.PingResponse> pingResponses = new ArrayList<>();

        for (ZenPing.PingResponse pingResponse : fullPingResponses) {

            DiscoveryNode node = pingResponse.node();

            //排除掉client节点

            if ((node.clientNode() || (!node.masterNode()&&                              !node.dataNode()))) { 

 

            }

            //排除掉单纯的数据节点

            elseif ((!node.masterNode() && node.dataNode())) {


            }

            //可以参与选举的节点

            else {

                pingResponses.add(pingResponse);

            }

        }

 

 

        final DiscoveryNode localNode = clusterService.localNode();

        List<DiscoveryNode> pingMasters = new ArrayList<>();

        //获取所有响应节点中的master节点

        for (ZenPing.PingResponse pingResponse : pingResponses) {

            if (pingResponse.master() != null) {

                if (!localNode.equals(pingResponse.master())) {

                    pingMasters.add(pingResponse.master());

                }

            }

        }

 

        Set<DiscoveryNode> activeNodes = Sets.newHashSet();

        //如果本节点配置为可以参与master的选举,

//将本节点加入候选节点进行选举

        if (localNode.masterNode()) {

            activeNodes.add(localNode);

        }

 

        for (ZenPing.PingResponse pingResponse : pingResponses) {

            activeNodes.add(pingResponse.node());

        }

 

        //集群没有一个正常的master,进行选举

        if (pingMasters.isEmpty()) {           

 //保证选举数量,候选节点数量需大于等于配置的数量

            if (electMaster.hasEnoughMasterNodes(activeNodes)) {

returnelectMaster.electMaster(activeNodes);

            }

            else {

                 returnnull;

            }

        }

        //集群中已经有一个正常的master,这时候接受那个master

else {

            return electMaster.electMaster(pingMasters);

        }

}

 

public DiscoveryNodeelectMaster(Iterable<DiscoveryNode> nodes) {

        //根据nodeId排序,选举第一个为master

        List<DiscoveryNode>sortedNodes = sortedMasterNodes(nodes);

        if (sortedNodes == null || sortedNodes.isEmpty()) {

            returnnull;

        }

        returnsortedNodes.get(0);

 }


这里来说明一下集群启动时master的选举场景:
假设有三个节点node1, node2, node3, 我们配置每个节点都有机会可以成为master(node.master: true)。

node1启动,此时node1去执行findMaster(),由于此时只有一个节点, node1只能发现自己这个节点, 不满足节点数大于n/2+1的条件(配置文件指定的),所以此时找不到master, node1会不断的执行while循环直到找到master位置。

然后node2启动,此时node2 通过ping可以发现node1,node1和node2构成了两个节点,可以知道activeNodes里面将会存放node1,node2,此时候选节点数量满足条件,选举并产生master节点。

此时node1 的循环又开始了,他就会发现master不是自己而是node2, 这样就会接受node2是master

然后第三个节点node3启动, 此时他也会执行while循环中的findMaster方法, 发现集群中已经有一个正常的master, 这时候也是接受那个master, 并加入集群。

文章转载自xbaobao,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论