投票配置

编辑

每个 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 都不会遭受“脑裂”不一致的困扰。cluster.auto_shrink_voting_configuration设置仅影响其在某些节点发生故障时的可用性,以及在节点加入和离开集群时必须执行的管理任务。

偶数个有资格成为主节点的节点

编辑

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

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

设置初始投票配置

编辑

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

重要的是,引导配置准确标识哪些节点应在第一次选举中进行投票。仅配置每个节点对集群中应有多少节点的期望是不够的。还必须注意,引导配置必须来自集群外部:集群无法以安全的方式自行正确确定引导配置。

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

为了说明为每个节点配置以期望特定集群大小的问题,请想象一下启动一个三节点集群,其中每个节点都知道它将成为三节点集群的一部分。三个节点的多数是两个,因此通常最先相互发现的两个节点形成一个集群,第三个节点在稍后加入它们。但是,假设错误地启动了四个节点而不是三个节点。在这种情况下,有足够的节点可以形成两个单独的集群。当然,如果每个节点都是手动启动的,那么不太可能启动太多节点。但是,如果您使用的是自动协调器,那么肯定有可能陷入这种情况——尤其是在协调器对诸如网络分区之类的故障没有弹性时。

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