版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

注意 本文参考的ES 5.0.1的源码

1. 查看集群状态

可以通过API查看集群状态

GET /_cluster/state

大致可以得到如下内容
cluster_state
version 集群状态数字版本号
每次更新version + 1
集群重启version不会置0(只会单调增)
state_uuid 是集群状态字符串版本号(UUID)
master_node master节点
nodes 该版本中的所有节点信息
routing_tablerouting_nodes 都是描述不同index上的shard在node上的分布关系

2. 集群状态的维护

ES源码中集群状态的对应类为ClusterState.java

The cluster state can be updated only on the master node. All updates are performed by on a single thread and controlled by the {@link ClusterService}. After every update the
{@link Discovery#publish} method publishes new version of the cluster state to all other nodes in the cluster.
In the Zen Discovery it is handled in the {@link PublishClusterStateAction#publish} method

  • 2.1 ClusterState是不可变对象,每次状态变更都会产生新的ClusterState,它们拥有不同的版本号

  • 2.2 在ES中, 集群状态由Master维护,并且只能由master节点更新集群状态

  • 2.3 更新完成后,Master会把新版本的集群状态推送给集群的其它所有节点
    对于publish,Master节点会根据它已知其它节点所拥有的集群状态版本,决定是执行
    sendFullClusterState()还是sendClusterStateDiff(), 前者是全量推送,后者增量推送。
    由于要推送给其它所有节点,如果集群的状态频繁变动,这个推动的开销其实也不小。

  • 2.4 对于使用Zen Discovery的情况,只要有minimumMasterNodes响应了Master节点的publish消息, 那么这次的commit就算成功

  • 2.5 另外需要补充的是Elasticsearch使用Gossip + Bully算法进行选主。Bully算法在具体实现中,不是简单选取节点ID小的节点, 首先要先比较ClusterState的版本。版本高的优先当选。(各个版本的ES实现有不同,但都需要考虑候选节点的集群状态版本)

    /**
     * Elects a new master out of the possible nodes, returning it. Returns <tt>null</tt>
     * if no master has been elected.
     */
    public MasterCandidate electMaster(Collection<MasterCandidate> candidates) {
        assert hasEnoughCandidates(candidates);
        List<MasterCandidate> sortedCandidates = new ArrayList<>(candidates);
        sortedCandidates.sort(MasterCandidate::compare);
        return sortedCandidates.get(0);
    }
        /**
         * compares two candidates to indicate which the a better master.
         * A higher cluster state version is better
         *
         * @return -1 if c1 is a batter candidate, 1 if c2.
         */
        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;
        }
    }

参考资料

  1. cluster-state

如果我的文章对你有帮助,你可以给我打赏以促使我拿出更多的时间和精力来分享我的经验和思考总结。

微信支付码

anyShare分享到:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.