知识库

理解因果集群规模扩展

安全地将因果集群的规模缩小能够在保持多数仲裁的前提下,为实例故障提供更高的鲁棒性。

在 3.4 之前,我们使用单个配置属性同时定义了“形成时所需的最小核心集群规模”和“缩减规模时的最小集群规模”。

causal_clustering.expected_core_cluster_size

自 3.4 起,上述配置属性已被废弃,其功能被拆分为两个独立的配置属性。

causal_clustering.minimum_core_cluster_size_at_formation

以及

causal_clustering.minimum_core_cluster_size_at_runtime

首个属性(形成时所需的核心集群规模)容易理解,而运行时的最小核心集群规模则稍显复杂,需要对 Raft 共识以及集群规模缩放有一定认识。

需要在此先说明,causal_clustering.minimum_core_cluster_size_at_runtime 的默认值 3 对大多数集群部署已经足够,并且能够在安全缩小集群规模时提供最佳效果。仅在非常特定的多数据中心需求或特殊场景下,才会考虑使用其它数值。

Raft 中的共识操作

因果集群使用 Raft 共识协议,该协议在大多数集群操作中都要求核心集群实例达到多数仲裁。

以下是一个易于理解的 可视化演练,展示 Raft 中分布式共识操作的过程。

虽然这通常被理解为适用于对集群的提交,同样也适用于对集群成员的投票(加入或退出)。

  • 将新成员接纳进集群需要多数仲裁。

  • 将成员踢出集群同样需要多数仲裁。

这两种操作都会改变核心集群成员的运行时规模,进而可能改变维持多数仲裁所需的核心成员数量,从而影响集群在失去仲裁(以及写入能力)之前能够容忍的故障数量。

将新成员投票加入集群

第一点相对容易理解。

这也是为什么当集群失去多数仲裁(和写入能力)时,不能通过动态添加新成员来恢复仲裁的原因:投票加入新成员必须得到在线集群成员的多数仲裁。

恢复仲裁的唯一途径是让足够多的离线实例重新上线(前提是它们并未因失去仲裁而被投票踢出)。

投票踢出成员并缩小集群

第二点相对更复杂。

当核心集群实例不再参与集群时(无论是计划内还是突发情况),都会发生(或至少尝试)投票踢出该实例的操作。

这可能是因为该实例的 Neo4j 被关闭或重启,实例主动向集群声明离开;也可能是更为意外的情况,如实例被杀死(或网络故障),导致在预期的超时时间内未收到心跳,集群的发现服务判定该实例离线。

此时,只要我们当前未达到 minimum_core_cluster_size_at_runtime,集群就会尝试将该实例投票踢出,前提是核心集群实例的多数仲裁仍在线。

若存在多数仲裁,则实例被投票踢出,核心集群规模相应缩减,所需的多数仲裁实例数随之改变。

若不存在多数仲裁,或已达到 minimum_core_cluster_size_at_runtime,则投票不会进行,实例无法被踢出;虽然该实例可能已离线,但从 Raft 的角度看集群规模无法进一步缩小,所需的多数仲裁数保持不变,容忍的故障数量也不变。

示例:集群规模为 3,最小集群规模为 3 的情况

causal_clustering.minimum_core_cluster_size_at_runtime 的默认值为 3。

这意味着当集群规模达到 3 并且失去一个实例后,无法再进一步缩小集群规模。

  • 如果这 3 个核心实例中的任意一个离线,即使我们仍然拥有 2 台实例的多数仲裁,也不会进行踢出投票。

  • 集群规模将保持在 3,不会缩减到 2。即使离线实例不可用,它仍被视为集群成员。

  • 当 3 台实例中只有 2 台在线时,若再有一台实例故障,集群将失去多数仲裁和写入能力。

  • 如果添加了其他核心实例,只要仍然保有 2 台实例的多数仲裁,就仍然可以将其投票加入。

示例:集群规模为 5,最小集群规模为 3 的情况

如果最初是一个 5 实例的集群,则多数仲裁为 5 台实例中的 3 台,并且在保持多数仲裁的前提下可以容忍 2 台实例同时故障。

当最多失去 2 台实例(不论是同步还是逐步、计划内还是计划外)时,会进行成员踢出投票并成功,因为仍然存在多数仲裁。此时集群规模会相应缩减为 3 实例,新的多数仲裁为 3 台中的 2 台,并且能够安全地再容忍一次实例故障而仍保持多数仲裁和写入能力。

换言之,当我们将集群缩减到 3 实例时,前述“集群规模为 3、最小集群规模为 3”的行为规则同样适用。

示例:集群规模为 5,最小集群规模为 5 的情况

如果最初是一个 5 实例的集群且最小集群规模也设为 5,则在出现实例故障时无法将集群规模缩小。

虽然可以容忍最多 2 台实例同时故障而仍保持多数仲裁,但不会发生集群规模缩减,也不会对实例进行踢出,进一步的实例丢失将导致失去多数仲裁和写入能力。

© . This site is unofficial and not affiliated with Neo4j, Inc.