我正在编写一个相当复杂的Go Webapp,希望使其高度可用。我计划让多个VM运行该应用程序,并使用负载均衡器将它们之间的流量引导到我想要的位置。

变得复杂的地方在于,Web应用程序正在运行某种数据库记账例程,我随时(最多)只需要一个实例。因此,如果我有三个webapp VM,则其中只有一个应该进行簿记。

(是的,我知道我可以将簿记完全拆分为一个单独的VM实例,但是代码已与Webapp的其余部分进行了高度集成。)

我花了几个小时来研究etcdraftbullymemberlistPacemaker等,等等。这些似乎都需要吸收很多信息才能完成我所追求的目标,或者我看不到使用它们的明确方法。

在这个特定的用例中,我想要的是一个系统,通过该系统,Go webapp节点可以自动相互检测并选举“领导者”进行簿记。理想情况下,它可以扩展到2到10个节点的任何位置,并且不需要手动将IP地址添加到配置文件中(但有可能,如有必要)。

我在网络分区或东西,其中一个节点无法看到其他人的情况下想,我不希望它本身选出作为一个领导者,因为这将是可能有两个节点试图做簿记在同一时间。这也意味着,如果我将集群缩减为一个虚拟机,则不会进行簿记,但是在维护期间可以容忍一小段时间,或者可以在某处设置某种标志。

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

最佳答案

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

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

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

关于web-applications - 参加Webapp集群负责人选举,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35108372/

10-09 16:01