知识库

集群形成与运行时的规模演示

因果集群形成时的最小核心规模

causal_clustering.minimum_core_cluster_size_at_formation 被定义为在形成集群时最初所需的最小核心机器数量。当至少有这么多核心成员相互发现时,集群即会形成。

下面的示例展示了一个拥有5个核心的集群,其中 causal_clustering.minimum_core_cluster_size_at_formation=3。核心 1 和 2 已初始化,第一次选举如下所示

2019-03-31 14:14:22.028+0000 INFO [o.n.c.n.Server] raft-server: bound to 127.0.0.1:7000
2019-03-31 14:14:22.038+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members...
2019-03-31 14:14:30.910+0000 INFO [c.n.c.d.SslHazelcastCoreTopologyService] Cluster discovery service started
2019-03-31 14:14:30.955+0000 INFO [c.n.c.d.SslHazelcastCoreTopologyService] Core topology changed {added=[{memberId=
MemberId{fb0bc6e1}, info=CoreServerInfo{raftServer=localhost:7001, catchupServer=localhost:6001,
clientConnectorAddresses=bolt://:7688,https://:7460,https://:7461, groups=[], database=default,
refuseToBeLeader=false}}, {memberId=MemberId{3811e9ed}, info=CoreServerInfo{raftServer=localhost:7000,
catchupServer=localhost:6000, clientConnectorAddresses=bolt://:7687,https://:7474,https://:7470,
groups=[], database=default, refuseToBeLeader=false}}], removed=[]}
2019-03-31 14:14:30.956+0000 INFO [o.n.c.c.c.m.RaftMembershipManager] Target membership: [MemberId{fb0bc6e1},
MemberId{3811e9ed}]
2019-03-31 14:14:31.022+0000 INFO [o.n.c.d.CoreMonitor] Discovered core member at localhost:5001
2019-03-31 14:14:32.099+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members...
2019-03-31 14:14:42.141+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members...
2019-03-31 14:14:52.188+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members...
2019-03-31 14:15:02.225+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members..

现在核心 3 加入,集群成功形成

2019-03-31 14:15:02.225+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members...
2019-03-31 14:15:12.281+0000 INFO [o.n.c.d.CoreMonitor] Waiting for a total of 3 core members...
2019-03-31 14:15:22.287+0000 INFO [o.n.c.d.CoreMonitor] Discovered core member at localhost:5002
2019-03-31 14:15:22.298+0000 INFO [c.n.c.d.SslHazelcastCoreTopologyService] Core topology changed
{added=[{memberId=MemberId{9274358d}, info=CoreServerInfo{raftServer=localhost:7002, catchupServer=localhost:6002,
clientConnectorAddresses=bolt://:7689,https://:7476,https://:7472, groups=[], database=default,
refuseToBeLeader=false}}], removed=[]}
2019-03-31 14:15:22.568+0000 INFO [o.n.c.d.CoreMonitor] This instance bootstrapped the cluster.

因果集群运行时的最小核心规模

causal_clustering.minimum_core_cluster_size_at_runtime 被定义为动态调整的投票集合的最小规模(投票集合只能包含核心成员)。随着核心成员的可用性变化(例如启动或停止成员的显式操作,或网络分区等意外问题),投票集合会自动调整。需要注意的是,这种投票集合的动态扩缩通常是可取的,因为在某些情况下它可以增加可容忍的实例故障数量。投票集合的多数必须可用,才能对成员进行投票加入或剔除。

让我们在一个 3 节点集群上尝试设置 causal_clustering.minimum_core_cluster_size_at_runtime=2。如果我们失去一个核心,集群仍然拥有共识,并可缩减到 2 个节点。但如果再失去一个,我们只剩下单节点且失去共识,无法再缩减,此时我们只能等待刚刚失效的节点重新上线。此时,如果最先失效的那个节点重新上线,由于缺乏共识,它无法重新加入集群。我们只能等最后一个失效的节点恢复。

在下面的示例中,核心 1(领导者)观察到核心 3 正如下面所示离开了集群

2019-03-31 15:10:31.234+0000 WARN [o.n.c.d.CoreMonitor] Lost core member at localhost:5002

此时,集群仍然在领导者核心 1 处拥有写入法定人数。但在随后的一段 causal_clustering.leader_election_timeout(默认 7 秒)后,核心 3 被从集群中移除——因为运行时的集群规模被设为 2。

如果我们随后也下线核心 2,集群将变为只读

2019-03-31 15:11:08.005+0000 INFO [o.n.c.c.c.s.RaftState] Leader changed from MemberId{e7f79e48} to null
2019-03-31 15:11:08.006+0000 INFO [o.n.c.c.c.s.RaftLogShipper] Stopping log shipper MemberId{a2ef543b}[matchIndex: 5,
lastSentIndex: 5, localAppendIndex: 5, mode: PIPELINE]

然而,如果我们现在先把核心 3 加回(核心 2 之前),仍然会得到两个处于 从属 状态的核心,导致集群保持只读,并且在核心 1 的日志中看到如下信息

2019-03-31 15:12:06.251+0000 DEBUG [o.n.c.c.c.RaftMachine] Should vote for raft candidate false: requester log up to date:
false (request last log term: 1, context last log term: 1, request last log index: 1, context last append: 5) voted for other
in same term: false (request term: 1, context term: 1, voted for another: false)

随后一次写入事务产生以下异常

Neo.ClientError.Cluster.NotALeader
Neo.ClientError.Cluster.NotALeader: No write operations are allowed directly on this database. Writes must pass through the
leader. The role of this server is: FOLLOWER

只有在核心 2 被重新加入后,三个核心才再次组成可写的集群

2019-03-31 15:13:04.377+0000 INFO [o.n.c.c.c.RaftMachine] Election started with vote request: Vote.Request from
MemberId{e7f79e48} {term=2, candidate=MemberId{e7f79e48}, lastAppended=5, lastLogTerm=1} and members: [MemberId{a2ef543b},
MemberId{e7f79e48}]
2019-03-31 15:13:04.377+0000 INFO [o.n.c.c.c.RaftMachine] Moving to CANDIDATE state after successful pre-election stage
2019-03-31 15:13:04.384+0000 INFO [o.n.c.c.c.RaftMachine] Moving to LEADER state at term 2 (I am MemberId{e7f79e48}), voted
for by [MemberId{a2ef543b}]
2019-03-31 15:13:04.384+0000 INFO [o.n.c.c.c.s.RaftState] First leader elected: MemberId{e7f79e48}

如果我们坚持使用默认的运行时集群规模 3,则集群无法缩减到 2(首个失效的节点不会被投票剔除),但我们能够保持共识和写入能力。但是当第二个节点失效、仅剩 1 个节点时,仍会失去共识和写入能力,情形与之前相同。不过,只要两个失效节点中的任意一个重新上线,我们即可恢复共识和写入能力,而不仅限于最近失效的节点。

总之,将 minimum_core_cluster_size_at_runtime 设置为 2 而非默认的 3,唯一实际的差别在于:当我们在将集群规模缩减到 2 后只剩下 1 个运行节点时,需要等待刚刚失效的节点重新上线,之前失效的节点无法重新加入,因为向集群添加“新”节点需要共识。

因此,当基础/静止的集群规模较大(例如 5)时,减小 minimum_core_cluster_size_at_runtime 才是更有意义的优化。在这种情况下,将 minimum_core_cluster_size_at_runtime 设为 3 而不是 5,使集群能够容忍 3 次故障(而不是 2 次)才失去写入能力,前提是这 3 次故障不会比集群剔除故障成员的速度(causal_clustering.leader_election_timeout)更快。将其设置为 2 而不是默认的 3 并不影响在 3 节点时对 1 次故障的容忍度。然而通常没有充分理由将其设为 2。对于拥有 5 台或更多核心的集群,可以将 minimum_core_cluster_size_at_runtime 设置为小于核心总数的值。

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