注意 本文参考的ES 5.0.1的源码
1. 查看集群状态
可以通过API查看集群状态
GET /_cluster/state
大致可以得到如下内容
version
集群状态数字版本号
每次更新version + 1
集群重启version不会置0(只会单调增)
state_uuid
是集群状态字符串版本号(UUID)
master_node
master节点
nodes
该版本中的所有节点信息
routing_table
和 routing_nodes
都是描述不同index上的shard在node上的分布关系
2. 集群状态的维护
可以阅读 .//core/src/main/java/org/elasticsearch/cluster/ClusterState.java
- 2.1 ClusterState是不可变对象,每次状态变更都会产生新的ClusterState,它们拥有不同的版本号
- 2.2 在ES中, 集群状态由Master维护,并且只能由master节点更新集群状态
-
2.3 更新完成后,Master会把新版本的集群状态推送给集群的其它所有节点 对于publish,Master节点会根据它已知其它节点所拥有的集群状态版本,决定是执行
sendFullClusterState()
还是sendClusterStateDiff()
, 前者是全量推送,后者增量推送。 - 2.4 对于使用Zen Discovery的情况,只要有minimumMasterNodes响应了Master节点的
publish
消息, 那么这次的commit
就算成功
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.5 另外需要补充的是Elasticsearch使用Gossip + Bully算法进行选主。Bully算法在具体实现中,不是简单选取节点ID小的节点, 首先要先比较ClusterState的版本。版本高的优先当选。(各个版本实现有不同,但都需要考虑候选节点的集群状态版本)
/** * 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; } }
参考资料
欢迎光临我的个人博客 萌叔 | http://vearne.cc
本文地址:http://elasticsearch.cn/article/711