zoukankan      html  css  js  c++  java
  • ES 选举Master节点机制

    ES采用主从模式架构,Master节点的选取对整个集群的可用性及数据一致性都起到了关键作用,下面介绍一下ES选取主节点的流程(版本6.1)

    整体流程

    选举临时Master节点,判断如果本节当选,则等待选票超过半数,成为真正的Master节点,如果本节点不是临时Master节点,则尝试加入集群,加入集群其实是投票的过程,整体流程如下:

    1 选取临时节点

    1.1 ping所有节点,获取节点列表fullPingResponses,并将自己添加到列表中

    1.2 构建目前存在的master列表activeMasters

    获取请求结果的所有节点的master节点

    List<DiscoveryNode> activeMasters = new ArrayList<>();
    for (ZenPing.PingResponse pingResponse : pingResponses) {
        // We can't include the local node in pingMasters list, otherwise we may up electing ourselves without
        // any check / verifications from other nodes in ZenDiscover#innerJoinCluster()
        if (pingResponse.master() != null && !localNode.equals(pingResponse.master())) {
            activeMasters.add(pingResponse.master());
        }
    }
    

    1.3构建master候选列表masterCandidates

    将ping获取的列表中,在启动时node.master true 的筛选出来,作为候选master

    List<ElectMasterService.MasterCandidate> masterCandidates = new ArrayList<>();
    for (ZenPing.PingResponse pingResponse : pingResponses) {
        if (pingResponse.node().isMasterNode()) {
            masterCandidates.add(new ElectMasterService.MasterCandidate(pingResponse.node(), pingResponse.getClusterStateVersion()));
        }
    }
    

    2 选择出临时master

    整体流程如下:

    • 判断activeMasters是否为空,如果不为空从activeMasters中选取一个节点作为临时主节点;
    public DiscoveryNode tieBreakActiveMasters(Collection<DiscoveryNode> activeMasters) {
        return activeMasters.stream().min(ElectMasterService::compareNodes).get();
    }
    

    直接使用选取排序后最小的作为临时master,比较器的规则:

    /** master nodes go before other nodes, with a secondary sort by id **/
        private static int compareNodes(DiscoveryNode o1, DiscoveryNode o2) {
        if (o1.isMasterNode() && !o2.isMasterNode()) {
            return -1;
        }
        if (!o1.isMasterNode() && o2.isMasterNode()) {
            return 1;
        }
        // 直接使用node的id进行比较
        return o1.getId().compareTo(o2.getId());
    }
    
    • 如果activeMasters为空,则从候选列表masterCandidates中选取一个作为临时主节点;

    masterCandidates中选取主节点时,首先需要判断候选人数是否达到了半数以上,当满足半数以上时,开始选择主节点,选择主节点的规则比较简单:

    public static int compare(MasterCandidate c1, MasterCandidate c2) {
        // we explicitly swap c1 and c2 here. the code expects "better" is lower in a sorted
        // list, so if c2 has a higher cluster state version, it needs to come first.
        int ret = Long.compare(c2.clusterStateVersion, c1.clusterStateVersion);
        if (ret == 0) {
            ret = compareNodes(c1.getNode(), c2.getNode());
        }
        return ret;
    }
    

    先比较集群状态的版本,选择集群状态版本较高的作为临时master,如果相同,则按照和activeMasters中选取的方式一样取ID较小的作为临时Master;

    确立Master或者加入集群

    • 如果本节点被选为临时Master,等待(默认30s)足够多节点加入本节点(超过一半)后,完成选举,并发布新的clusterState
    • 如果其他节点本选为临时Master节点,向Master节点发送加入集群的请求,等待(1分钟)回复,最终master会发布集群状态,并确认客户join请求;

    如果以上处理失败,则重新开始新一轮的选举;

    节点失效监测

    • Master节点启动NodesFaultDetection定期监测加入集群的节点是否活跃;
    • 非Master节点启动MasterFaultDetection定期监测Master节点是否活跃;

    节点监测都是通过定期(1s)发送ping探测节点是否正常,如果超过3次,则开始处理节点离开事件;

    NodesFaultDetection事件处理

    检查集群是否达到了法定节点数(过半),如果不足,则放弃Master重新加入集群,这样做的目的是为了防止产生双主,例如集群中有5个节点[A,B,C,D,E],A为主节点,由于某种原因,集群网络出现分区[A,B],[C,D,E],这时候[C,D,E] 组成的分区监测不到主节点开始处理MasterFaultDetection重新选举主节点,假设选举C为主节点;由于A节点无法监测到[C,D,E]三个节点,开始处理NodesFaultDetection,这时候如果A所在分区如果不监测法定节点数,继续作为主节点;整个集群会出现两个主节点A,C;

    MasterFaultDetection事件处理

    监测到主节点离线后回重新监测法定节点数,并进行新一轮的选择;

    I am chris, and what about you?
  • 相关阅读:
    清除/var/spool/clientmqueue/目录下的文件
    欧几里德法求最大公约数
    博客园美化
    Vue.js学习笔记-script标签在head和body的区别
    C++ 继承
    Ubuntu 更换软件源/镜像源
    12306火车票余票查询&Python实现邮件发送
    饥荒联机代码
    linux内核编程入门 hello world
    windows环境下使用C++&Socket实现文件传输
  • 原文地址:https://www.cnblogs.com/arax/p/14426285.html
Copyright © 2011-2022 走看看