投票配置

编辑

每个 Elasticsearch 集群都有一个投票配置,它是一组主节点候选节点,在做出决策时(例如选举新的主节点或提交新的集群状态)会统计这些节点的响应。只有当投票配置中超过一半的节点做出响应后,才会做出决策。

通常,投票配置与当前集群中所有主节点候选节点的集合相同。但是,在某些情况下,它们可能不同。

为了确保集群保持可用,您绝不能同时停止投票配置中一半或更多节点。只要超过一半的投票节点可用,集群就可以正常工作。这意味着,如果有三个或四个主节点候选节点,集群可以容忍其中一个不可用。如果有两个或更少的主节点候选节点,则它们都必须保持可用。

如果您同时停止投票配置中一半或更多节点,则集群将不可用,直到您将足够多的节点恢复联机以再次形成仲裁。在集群不可用期间,任何剩余的节点都将在其日志中报告无法发现或选举主节点。有关更多信息,请参见发现故障排除

节点加入或离开集群后,Elasticsearch 会自动对投票配置进行相应的更改以确保集群尽可能具有弹性。在从集群中移除更多节点之前,等待此调整完成非常重要。有关更多信息,请参见在集群中添加和移除节点

当前投票配置存储在集群状态中,因此您可以按如下方式检查其当前内容

resp = client.cluster.state(
    filter_path="metadata.cluster_coordination.last_committed_config",
)
print(resp)
response = client.cluster.state(
  filter_path: 'metadata.cluster_coordination.last_committed_config'
)
puts response
const response = await client.cluster.state({
  filter_path: "metadata.cluster_coordination.last_committed_config",
});
console.log(response);
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 都不会出现“https://en.wikipedia.org/wiki/Split-brain_(computing)[脑裂]”不一致。 cluster.auto_shrink_voting_configuration 设置仅影响其在某些节点发生故障以及节点加入和离开集群时必须执行的管理任务时的可用性。

偶数个主节点候选节点

编辑

集群中通常应该有奇数个主节点候选节点。如果有偶数个,Elasticsearch 会将其中一个节点排除在投票配置之外,以确保其大小为奇数。此省略不会降低集群的容错能力。事实上,它略微提高了容错能力:如果集群出现网络分区,将其分成两个大小相等的部分,则其中一部分将包含投票配置的大多数,并且能够继续运行。如果统计所有主节点候选节点的投票,则任何一方都不会包含严格多数的节点,因此集群将无法取得任何进展。

例如,如果集群中有四个主节点候选节点,并且投票配置包含所有这些节点,则任何基于仲裁的决策都需要至少三个节点的投票。这种情况意味着集群只能容忍一个主节点候选节点丢失。如果此集群被分成两个相等的部分,则任何一部分都不会包含三个主节点候选节点,并且集群将无法取得任何进展。但是,如果投票配置仅包含四个主节点候选节点中的三个,则集群仍然只能完全容忍一个节点丢失,但基于仲裁的决策需要三个投票节点中的两个节点的投票。如果发生平均拆分,则其中一部分将包含三个投票节点中的两个,因此该部分将保持可用。

设置初始投票配置

编辑

当全新的集群首次启动时,它必须选举其第一个主节点。为了进行此选举,它需要知道应该统计哪些主节点候选节点的投票。此初始投票配置称为引导配置,在集群引导过程中设置。

引导配置必须准确地识别哪些节点应该在第一次选举中投票。仅为每个节点配置对集群中应该有多少节点的预期是不够的。还必须注意,引导配置必须来自集群外部:集群本身没有安全的方法来正确确定引导配置。

如果引导配置设置不正确,则在启动全新的集群时,您可能会意外地形成两个单独的集群而不是一个。这种情况可能导致数据丢失:您可能会在注意到任何错误之前就开始使用这两个集群,并且以后无法将它们合并在一起。

为了说明为每个节点配置对特定集群大小的预期的存在的问题,假设启动一个三节点集群,其中每个节点都知道它将成为三节点集群的一部分。三个节点的大多数是两个,因此通常,前两个发现彼此的节点形成一个集群,第三个节点在稍后加入它们。但是,假设错误地启动了四个节点而不是三个。在这种情况下,有足够的节点可以形成两个单独的集群。当然,如果手动启动每个节点,则不太可能启动太多节点。但是,如果您使用的是自动编排器,则肯定有可能出现这种情况,尤其是在编排器对网络分区等故障没有弹性时。

初始仲裁仅在整个集群首次启动时需要。加入已建立集群的新节点可以安全地从已选举的主节点获取所有必要的信息。以前是集群一部分的节点将在重新启动时将所有必要信息存储到磁盘中。