问题描述
我正在寻找一种将新成员添加到现有 Aeron 集群而无需重新配置现有集群的方法。
似乎集群成员定义为 statically during startup,如集群教程中所述:
final ConsensusModule.Context consensusModuleContext = new ConsensusModule.Context()
.errorHandler(errorHandler("Consensus Module"))
.clusterMemberId(nodeId)
.clusterMembers(clusterMembers(Arrays.asList(hostnames))) // <------ HERE
.clusterDir(new File(baseDir,"consensus-module"))
.ingressChannel("aeron:udp?term-length=64k")
.logChannel(logControlChannel(nodeId,hostname,LOG_CONTROL_PORT_OFFSET))
.replicationChannel(logReplicationChannel(hostname))
.archiveContext(aeronArchiveContext.clone());
如果我理解正确,如果我想添加更多节点,我需要重新配置每个现有节点以包含新成员。
此外,我在Aeron Cookbook(强调我的)中发现了这个
Raft 的关键方面:
- 有一个强大的领导者,这意味着所有的日志条目都从领导者流向追随者
- Raft 使用随机计时器来选举领导人。 This adds a few milliseconds to failover,but reduces the time to agree an elected leader (in Aeron Cluster,this is a maximum of the election timeout * 2).
- Raft 协议允许运行时配置更改(即在运行时添加新节点或删除节点)。 在撰写本文时,此功能仍在 Aeron Cluster 中待定。
但是,我确实看到了 io.aeron.cluster.DynamicJoin
之类的类及其在 io.aeron.cluster.ConsensusModuleAgent
中的用法,这让我觉得动态添加节点是可能的,也许说明书已经过时了。
你知道一种在不接触现有节点的情况下加入更多节点的方法吗?
解决方法
是的,这是可能的!上下文应该像这样构建:
ConsensusModule.Context()
.errorHandler(errorHandler("Consensus Module"))
.clusterMemberId(Aeron.NULL_VALUE) // <1>
.clusterMembers("") // <2>
.memberEndpoints(memberEndpoints(hostnames[nodeId],nodeId)) // <3>
.clusterConsensusEndpoints(consensusEndpoints(hostnames)) // <4>
.clusterDir(File(baseDir,"consensus-module"))
.ingressChannel("aeron:udp?term-length=64k")
.logChannel("aeron:udp?term-length=64k")
.replicationChannel(logReplicationChannel(hostname))
.archiveContext(aeronArchiveContext.clone())
-
clusterMemberId
必须设置为Aeron.NULL_VALUE
。会员ID会自动生成 -
clusterMembers
应该是空的。动态节点不需要静态成员 -
memberEndpoints
是这个节点的通道配置。格式为ingress:port,consensus:port,log:port,catchup:port,archive:port
。非常类似于单个节点的 staticclusterMembers
configuration,但前面没有成员 ID。 -
clusterConsensusEndpoints
是以逗号分隔的列表consensus:port 已知集群成员的频道。我认为它类似于要加入的主机的“引导程序”列表。