Go Webapp 集群领导者选举

Go Webapp Cluster Leader Election

我正在编写一个相当复杂的 Go 网络应用程序,我希望它具有高可用性。我计划使用多个 VM 运行 应用程序,并使用负载均衡器根据我的需要在它们之间引导流量。

它变得复杂的地方是 webapp 有一种数据库簿记例程 运行,我在任何时候(最多)只想要一个实例。因此,如果我有三个 webapp VM,则只有其中一个应该做簿记。

(是的,我知道我可以将簿记完全拆分到一个单独的 VM 实例中,但是代码已经与 web 应用程序的其余部分高度集成。)

我花了几个小时查看 etcd, raft, bully, memberlist, Pacemaker 等内容。这些似乎都需要吸收很多信息才能完成我所追求的目标,或者我看不到使用它们的明确方法。

在这个特定的用例中,我想要的是一个系统,Go webapp 节点可以自动检测彼此并选择一个 "leader" 来做簿记。理想情况下,这可以扩展到 2 到 10 个节点,并且不需要手动将 IP 地址添加到配置文件(但如果需要,可以)。

我在考虑在网络分区或其他情况下,一个节点看不到其他节点,我不希望它选择自己作为领导者,因为有可能有两个节点试图同时做簿记。这也意味着,如果我将集群剥离为单个 VM,则不会发生簿记,但在维护期间可以容忍一小段时间,或者我可以在某处设置某种标志。

我想知道是否有人可以为我指明正确的方向,希望我如何以低复杂度完成此任务,同时尽可能利用现有代码库。

根据您的容错性和一致性要求——特别是防止分区中的脑裂——像 Raft 这样的共识算法是您最想要的。但即使 Raft 是为易于理解而设计的,它仍然需要大量的专业知识才能正确实施。因此,正如其他人提到的那样,您应该研究现有的服务或实现。

ZooKeeper (ZAB), etcd (Raft), and Consul (Raft) 是执行此类操作的最广泛使用的系统。考虑到您希望 VM 从 2 个节点扩展到 10 个节点,这很可能是您想要的方式。 Raft 和其他共识算法具有法定人数要求,如果算法直接嵌入到您的 VM 中,则以这种方式进行扩展不太实用。通过使用外部服务,您的 VM 可以简单地成为共识服务的客户端,并且可以独立于它进行扩展。

或者,如果您不想依赖外部服务进行协调,Raft website 有各种语言的详尽列表,其中一些是共识服务,一些可以嵌入.但是,请注意,其中许多是不完整的。至少,任何适用于生产的 Raft 实现都必须实现日志压缩。如果没有日志压缩,服务器实际上只能运行有限的时间——直到磁盘填满日志。