1. 简介
elasticsearch的节点发现和cluster组建module主要有以下功能。
- 节点发现
- master选举
- 在cluster state 发生变化后将其在cluster中publish
当然这个模块也集成了其他模块的功能,比如node之间的通信使用了transpost module
主要包含以下几个部分的内容 - 节点发现: 节点发现是指master不存在的时候node如何发现彼此,一般是集群开始启动或者之前的master挂掉了的情况。
- 多数生效的操作: 主要讲述elasticsearch在即使少数nodes不工作的情况下也能够正常作出decision的quorum-based voting机制
- 投票人信息设置: elasticsearch 的可以参与投票的节点信息的设置,elasticsearch会在node 假如或者离开的时候自动更新这个设置
- cluster的启动过程: 集群启动的过程以及需要的配置
- add或者remov 一个 master-eligible node需要注意的事情
- 发布cluster的state: 这个过程只有master能够执行
- 集群的故障检测功能
- 一些设置信息
2. 节点发现
节点发现是集群组建模块查找与之形成集群的其他节点的过程。当您启动Elasticsearch节点或节点认为master节点发生故障时,此过程将运行,并持续到找到主节点或选举出新的主节点为止。
在elasticsearch.yml文件中一般有以下配置
discovery.seed_hosts: ["10.66.0.189:9300","10.66.4.45:9300","10.66.0.239:9300","10.66.2.173:9300"]
cluster.initial_master_nodes: ["ES01", "ES02","ES03"]
节点发现的过程一般是node通过elasticsearch.yml中配置的discovery.seed_hosts
和当前node中存储的之前的cluster-state中记录的master-eligible nodes 作为seed address(种子服务地址)来开始进行节点发现的。
这个过程分为两个阶段:
- 每个node都请求他的seed address简历连接,然后verify这个node是否是一个master-eligible node。
- 如果第一步连接成功了并执行了相应的请求之后,当前node会和这些node相互share他们发现的master-eligible node list,然后当前node如果拿到了新的master-eligible node,那么他会再向这些新的node发起请求,重复这个过程。
说明
- 如果当前node不是一个master-eligible node ,那么他会持续这个discovery过程,直到他发现了一个elected master node。如果没有发现elected master node,当前节点会在 1s钟以后进行重试(discovery.find_peers_interval)
- 如果当前node是一个master-eligible node ,那么他会持续这个discovery过程,直到他发现了一个elected master node,或者是找到足够数量的master-eligible node来进行一次master选举。在没有满足以上两种情况的时候,他会在1s以后进行重试(discovery.find_peers_interval)
3. 多数生效的操作
Quorum-based decision making
主要讲述elasticsearch在即使少数nodes不工作的情况下也能够正常作出decision的quorum-based voting机制
elasticsearch是一个由多个节点组成的分布式集群,在这个集群中有一部分节点是master-eligible node, 其他的节点一般是data node, 在运行的过程中只有一个master-eligible node会成为实际上的master node。cluster的state总是由当前master在整个集群中进行publish操作。那么cluster-state的数据的一致性是需要保障的,比如说当前的master如果宕机了,那么应该选取哪个master-eligible node呢,如果所有的master-eligible node 都有一样的cluster-state数据,那么选择哪个成为新的master都可以,但是这种情况下就是当前master在决定记录一个cluster-state的时候会等所有的master-eligible node 都确认可以保存了才会记录该cluster-state。这种情况下如果有一个master-eligible node在集群运行的过程中挂掉了,那么整个cluster-state就无法再进行发布,集群也就无法正常工作了。所以elasticsearch使用的是quorum-base的工作模式,比如在master决定某个cluster-state是否可以保存的时候不是等待所有的master-eligible node 都确认,而是等到一定数量的master-eligible node确认后就认为这个cluster-state可以保存了,这个一定数量的master-eligible node 就被称为quorum-base的工作模式。这种情况下,即使有少数的master-eligible node 发生了宕机,整个cluster仍然可以继续运行下去,集群的鲁棒性得到了很大的提升。但是这个quorums 需要谨慎选择以避免脑裂等问题的发生。
Quorum-based decision making 的主要使用场景就是clustet-state进行commit的管理和master 的选举。
elasticsearce的quorum是这样计算的,假如master-eligible node 的数量是n 则 quorum=(n+1)/2,需要注意的是n的数量需要为奇数,即使你有偶数个,elasticsearch也会忽略掉一个。
当然这个内部还有细节,我们后面会展开详述,实际上比这个更灵活一些也更复杂一些,elasticsearch内部实际上是通过Voting configurations这个设置来维护quorum的。
所以,如果你需要从cluster剔除部分master-eligible node 的话,不能一次剔除太多,理论上要小于master-eligible node一半的数量。当然,如果你剔除的不是master-eligible node的话对集群的可用性是没有影响的,主要就考虑你的数据备份情况了。
4. 投票人信息设置
Voting configurations
elasticsearch 的可以参与投票的节点信息的设置,elasticsearch会在node 加入或者离开的时候自动更新这个设置,这个信息也是产生quorum-base的基础。
Voting configurations 保存的是参与决策的master-eligible node 的信息,参与决策是指在进行master electing或者是committing一个cluster-state的时候需要这些master-eligible node的投票。
只有在大多数的node(超过一半数量)都确认了之后操作才算成功(比如cluster-state可以进行commit或者master elect成功)。这里的超过一半就是指上面的quorum-base。
1. Voting configurations 中的节点信息
- 偶数的master-eligible node : 如果当前集群内存在的master-eligible node 的数量是偶数n的话,那么Voting configurations 中只会记录n-1个node的信息。
- 其他情况下正常情况下Voting configurations 中保存的就是当前cluster中的所有的master-eligible node 。
- 在cluster中的master-eligible node 增加或者减少的情况下Voting configurations 中的节点信息 如何变化可以配置策略
- 集群在第一次start的时候根据elasticsearch.yml中配置的
cluster.initial_master_nodes
来初始化Voting configurations
2. Voting configurations 为何只保留奇数的master-eligible node
拿cluster-state的更新来举例子,因为采用的是quorum-base的策略,所以是超过一半的数的节点同意后才能进行commit操作,假如一个节点有4个master-eligible node。
那么如果这4个都记录在Voting configurations 当中的话,那么quorum的数量就必须是3,当集群产生分区后的每个分区都是2个node的话,那么该集群将不能工作,因为两边都没有3个节点。
但是假如Voting configurations 记录的是3个节点的数量的话,那么quorum的数量就是2,当集群产生分区后的每个分区都是2个node的话,那么肯定是某一个集群是可以工作的,另一个是不能工作的。
假如是节点宕机的话,两种情况下的容忍度都是1。
所以相对来说这种配置比Voting configurations 中直接存储的时候4个节点的情况具备更高的可用性。
3. cluster进行增减master-eligible node 的时候Voting configurations 的变化
正常情况下的建议是集群中的master-eligible node 是固定的,在集群伸缩的时候主要是对data node进行增减。
但是有些时候我们确实也需要对master-eligible node 进行增减操作,这个时候需要注意些什么呢
1. Voting configurations 的管理策略
elasticsearch对Voting configurations 的管理可以使用不同的策略。默认的情况下elasticsearch会在add remove的时候自动对Voting configurations 进行维护。这个可以通过cluster.auto_shrink_voting_configuration
进行设置。
默认情况下这个设置是true,也就是es会自动调整,如果设置为false了,就必须要通过api来手动管理Voting configurations 了。
当然,如果设置为true了你依然可以通过对应的api来进行管理Voting configurations
需要注意的一点是cluster.auto_shrink_voting_configuration
生效的情况只有在cluster中的master-eligible node的数量大于等于3个的时候才能生效。如果集群中当前有3个,然后master挂掉了,这个时候集群是正常的,但是集群不会进行Voting configurations 的收缩,也就是当集群再挂掉一个master的时候那么集群就是不可用的了。
2. 增加master-eligible node
在一个稳定的集群中增加一个或者多个master-eligible node的时候,这个新的node会发起一个join request 到当前的cluster中的master节点来正式的加入集群。
这个请求的默认超时时间是30s(cluster.join.timeout)
3. 移除master-eligible node
正常情况下,在开启了cluster.auto_shrink_voting_configuration
设置的情况下,如果你移除的master-eligible node的数量少于当前集群中总的master-eligible node数量的一半的话,不用担心,elasticsearch会自动做一些调整,同时集群始终是可以提供服务的状态。
当时如果你同时移除的master-eligible node的数量大于等于总数的一半的时候,你就不能直接移除了,因为elasticsearch这个时候会认为quorum不足,集群也就没有办法正常工作了。
如果想要移除一半以上的master-eligible node那么只能通过 Voting Configuration Exclusions API 来进行操作了。
# 在voting configuration exclusions list 添加一个node,会等待30s(默认的时间)来让auto-reconfigure 完成
POST /_cluster/voting_config_exclusions/$node_name
#在voting configuration exclusions list 添加一个node,会等待1min(默认的时间)来让auto-reconfigure 完成
POST /_cluster/voting_config_exclusions/$node_name?timeout=1m
同样需要注意的是,只有在同时移除一半以上的master-eligible node的时候才需要使用Exclusions API,而且voting configuration exclusions list 默认的最大值是10,可以通过cluster.max_voting_config_exclusions
控制
还有非常重要的一点是,在使用完exclusions list之后需要进行复位,也就是说一个健康的,正在运行的cluster的exclusions list 应该是空的。
通过这个查看当前的exclusions list
GET /_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions
# 等待所有nodec处理完成的模式
DELETE /_cluster/voting_config_exclusions
# 立即返回模式
DELETE /_cluster/voting_config_exclusions?wait_for_removal=false
4. cluster第一次start的时候如何初始化Voting configurations
虽然elasticsearch 使用quarum-base的方式进行master elect ,但是这个时候Voting configurations 还没有设置完,所以quarum-num也是没有办法计算的。
这个时候如果仅仅是通过配置discovery.seed_hosts
来通过查找的方式来初始化Voting configurations 也是不可靠的,因为并不知道到master-eligible node到底有多少个
所以初始化的时候必须要通过外部配置来识别有哪些master-eligible node
cluster.initial_master_nodes: ["ES01", "ES02","ES03"]
这里使用的是每个master-eligible node的node.name
注意事项:
- 每个master-eligible node都要配置一样的
cluster.initial_master_nodes
- 对于master-ineligible nodes 不需要设置这个属性
- 对于要要加入一个已经存在的cluster的master-eligible nodes 也不需要设置这个属性
- 在cluster进行restart的时候也不需要再设置这个属性
也就是在实际使用中只有第一次创建cluster的时候这个是有用的,当然,实际使用中发现对于2,3,4条即使多设置了也不会有影响。
开发者模式
如果node的elasticsearch.yml中没有任何以下配置的时候,es启动的时候会使用开发者模式
discovery.seed_providers
discovery.seed_hosts
cluster.initial_master_nodes
在开发者模式下只会尝试连接本机的其他node来组件一个cluster,但是不会连接其他机器的节点
生产模式下一定注意要配置
discovery.seed_hosts
cluster.initial_master_nodes
7. 发布cluster的state
这个过程只有master能够执行,master node是cluster中唯一能够修改cluster-state的节点。
这个过程类似于一个两阶段提交。master 会使用batch的方式来更新cluster-state,这样可以避免更新的频次过于频繁。
1. 成功的两阶段提交
1. 阶段一
- master向集群中的所有node 广播(broadcast) 更新后的cluster state
- 每一个node在收到master的这个广播消息后会对消息进行预提交,如果确认本机可以提交的话会给master返回ack信息
2. 阶段二
- master在收到超过半数的(quorum-base)的master-eligible node的ack信息之后就会认为这个消息可以commit了,master会进行commit,然后再给cluster中的其他节点发送commit消息
- 其他节点在收到该消息后会对阶段一收到的cluster state进行正式的提交,然后给master回复ack信息
2. 可能出现的错误
这个两阶段提交的过程也是可能出现错误的,第一类是超时错误,这个过程肯定有时间限制,在一定时间内未完成两阶段的提交则会出现不同的处理方式。
elasticsearch使用 cluster.publish.timeout
来控制整个过程的耗时默认是30s。
超时发生在第一阶段和第二阶段elasticsearch又会作出不同的反应。
1. 在第一阶段发生超时
也就是说master在广播完cluster state的信息后,在cluster.publish.timeout
的时间内并没有收到quorum-num的master-eligible node的ack回应。
那么当前master会认为自己的号召力不够,不会保存这个cluster-state,然后退位发起一次master选举。
2. 在第二阶段发生超时
如果第一个阶段正常完成了,master会认为这个update是成功的,对这个cluster-state进行commit, 然后向其他node broadcast commit信息。
然后master会等待其他node ack的消息,在这个时候如果达到cluster.publish.timeout
设置的时间了,那么master会接着进行下一轮的cluster-state的处理工作,
同时master会记录那些没有还没有回复ack的节点(这些节点有可能是在阶段一有可能是在阶段二),这些node被认为是落后节点,对于这些落后节点,master会给他们一些额外的时间来跟上master,
如果在cluster.follower_lag.timeout
的时间内没有完成这次cluster-state的更新,那么就可以认为这个node 挂掉了,然后这个node就会被从cluster当中踢出去。
cluster-state的更新采用的是增量更新的方式,这样的话更新的数据就会更少,集群的压力也更小。
当然对于那些rejoin或者是new-join的node,master会针对该node做一次full-cluster-state的同步,然后后面再使用增量同步的方式进行cluster-state的同步。
elasticsearch是一个点对点的系统,正常的操作比如index,delete,search等并不会对master产生影响,master只负责集群的全局信息和当node 离开或者加入cluster时候产生的reassign shards 信息
8. 集群的故障检测功能
集群中的master会定期的检测cluster中的每一个node来确保他们都处于connected的状态而且是healthy的状态,这个过程被称为follower check。
其他的node也会周期性的检测master的health,这个过程被称为leader check。
elasticsearch允许这些check偶尔的失败或者超时,之后连续数次的失败或者超时的时候,才会认为对方不可用了。可以通过cluster.fault_detection.*
来设置这些设置。
然而,如果master发现一个node不能被connected了,那么就会跳过timeout机制,直接尝试remove 这个node。同样的,当一个node发现master不能被connected的时候他也会立刻进行discovery的过程。
可能是找到master或者重新选出一个新的master