投票配置
每个 Elasticsearch 集群都有一个投票配置(voting configuration),它是在做出决策(例如选举新主节点或提交新集群状态)时统计其响应的主合格节点集合。只有在投票配置中超过一半的节点响应后才会做出决策。
通常投票配置与当前集群中所有主合格节点的集合相同。但是,在某些情况下它们可能不同。
为确保集群保持可用,你不得同时停止投票配置中一半或更多的节点。只要超过一半的投票节点可用,集群仍能正常工作。这意味着如果有三或四个主合格节点,集群可以容忍其中一个不可用。如果只有两个或更少的主合格节点,则它们必须全部保持可用。
如果你同时停止了投票配置中一半或更多的节点,则集群将不可用,直到你让足够多的节点重新上线以再次形成法定人数。当集群不可用时,任何剩余节点都会在其日志中报告它们无法发现或选举主节点。更多信息参阅发现故障排除。
在节点加入或离开集群后,Elasticsearch 会自动对投票配置进行相应的更改,以确保集群尽可能有弹性。在从集群中移除更多节点之前,等待此调整完成非常重要。更多信息参阅在集群中添加和移除节点。
当前投票配置存储在集群状态中,你可以按如下方式检查其当前内容:
GET /_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config
当前投票配置不一定与集群中所有可用的主合格节点的集合相同。更改投票配置涉及进行投票,因此在节点加入或离开集群时调整配置需要一些时间。此外,在某些情况下,最具弹性的配置可能包括不可用的节点或不包括某些可用的节点。在这些情况下,投票配置与集群中可用的主合格节点集合不同。
更大的投票配置通常更有弹性,因此 Elasticsearch 通常倾向于在主合格节点加入集群后将它们添加到投票配置中。类似地,如果投票配置中的节点离开集群而集群中存在不在投票配置中的另一个主合格节点,则最好将这两个节点互换。这样投票配置的大小不变,但其弹性增加。
在节点离开集群后自动将它们从投票配置中移除并不那么简单直接。不同的策略有不同的优点和缺点,因此正确的选择取决于集群的使用方式。你可以使用 cluster.auto_shrink_voting_configuration 设置控制投票配置是否自动收缩。
如果 cluster.auto_shrink_voting_configuration 设置为 true(这是默认值和推荐值),并且集群中至少有三个主合格节点,那么只要其主合格节点中除一个之外都健康,Elasticsearch 就保持能够处理集群状态更新。
在某些情况下,Elasticsearch 可能会容忍多个节点的丢失,但这并不能保证在所有失败序列下都成立。如果 cluster.auto_shrink_voting_configuration 设置为 false,你必须手动从投票配置中移除离开的节点。使用投票排除 API 来实现所需的弹性水平。
无论如何配置,Elasticsearch 都不会遭受"脑裂"不一致的影响。cluster.auto_shrink_voting_configuration 设置只影响它在某些节点发生故障时的可用性,以及节点加入和离开集群时必须执行的管理任务。
偶数个主合格节点
集群中通常应该有奇数个主合格节点。如果有偶数个,Elasticsearch 会将其中一个排除在投票配置之外,以确保投票配置具有奇数大小。这种排除不会降低集群的容错能力。事实上,它会略微改善容错能力:如果集群遭受将其分成两个大小相等的部分的网络分区,则其中一部分将包含投票配置的大多数并能继续运行。如果统计来自主合格节点的所有投票,则任何一方都不会包含节点的严格多数,因此集群将无法取得任何进展。
例如,如果集群中有四个主合格节点且投票配置包含所有这些节点,任何基于法定人数的决策都需要其中至少三个的投票。这种情况意味着集群只能容忍单个主合格节点的丢失。如果此集群被分成两个相等的部分,两部分都不会包含三个主合格节点,集群将无法取得任何进展。然而,如果投票配置只包含四个主合格节点中的三个,集群仍然只能完全容忍一个节点的丢失,但基于法定人数的决策需要三个投票节点中的两个的投票。在发生均分的情况下,其中一部分将包含三个投票节点中的两个,从而该部分保持可用。
设置初始投票配置
当一个全新的集群首次启动时,它必须选举其第一个主节点。要进行此选举,它需要知道哪些主合格节点的投票应该被统计。此初始投票配置称为引导配置(bootstrap configuration),在集群引导过程中设置。
引导配置必须准确标识哪些节点应在第一次选举中投票,这一点非常重要。仅仅为每个节点配置对集群中应有节点数量的预期是不够的。同样重要的是要注意,引导配置必须来自集群外部:集群自身没有安全的方式来正确确定引导配置。
如果引导配置设置不正确,当你启动一个全新的集群时,存在意外形成两个单独集群而不是一个的风险。这种情况可能导致数据丢失:你可能在注意到任何问题之前就开始使用这两个集群,之后不可能再将它们合并在一起。
为了说明为每个节点配置预期集群大小的问题,想象一下启动一个三节点集群,其中每个节点都知道它将成为三节点集群的一部分。三个节点的多数是两个,因此通常前两个相互发现的节点组成集群,第三个节点稍后加入它们。但是,想象一下错误地启动了四个节点而不是三个。在这种情况下,有足够的节点形成两个单独的集群。当然,如果每个节点都是手动启动的,那么启动过多节点的可能性不大。然而,如果你使用自动化编排器,则完全可能陷入这种情况 — 特别是如果编排器对诸如网络分区之类的故障没有弹性时。
初始法定人数只在整个集群第一次启动时需要。加入已建立集群的新节点可以安全地从已选举的主节点获取它们需要的所有信息。以前曾是集群一部分的节点在重启时将已在磁盘上存储了所需的所有信息。