代码之家  ›  专栏  ›  技术社区  ›  djna

避免头脑分裂、投票和法定人数[关闭]

  •  14
  • djna  · 技术社区  · 16 年前

    假设您有n个进程,n>2。你想在他们之间达成协议,一个是积极的。所以他们需要互相投票来决定谁是活跃的。

    所有进程可能在任何时候都会失败,如果可能,我们希望有一个进程处于活动状态,但是…

    我们 必须 不要同时有两个活动,所以如果他们不能确定最好没有一个活动。(也就是说,我们要避免大脑分裂)

    它们之间唯一可用的通信机制是pub子消息传递(而不是点对点)。

    一个或多个数据库可用,但任何一个数据库都不应是单点故障。也就是说,如果所有的进程都可以工作,并且由于丢失了一个数据库而不能这样做,那将是非常不合适的。

    设计?需要发布哪些消息?

    3 回复  |  直到 8 年前
        1
  •  29
  •   Jason Watkins    8 年前

    理论:

    这是领袖选举,是 Consensus Problem ,有时也称为 The Two Generals Problem . 在一些假设下(完全异步和消息可能丢失),这已经被证明是不可能的,而且证明特别优雅。

    这个问题的直觉是:假设存在某种算法,允许在固定数量的消息中达成共识。由于故障是可以容忍的,所以我们可以从协议中删除一条消息,它仍然可以工作。我们可以重复这个过程,直到完全没有消息,显然是不可能的。

    在实践中,我们使用故障检测器来模拟同步系统来克服这一问题。

    最广为人知的解决共识的算法是 Paxos ,最多可承受一半参与节点的故障。Paxos的名声是很难实现,因为对协议细节的细微误解会破坏协议的正确性。

    实际解决方案:

    虽然一般来说,这个问题很难解决,但是让工作系统运行起来要容易得多。有现成的paxos或等效算法的实现。 Apache Zookeeper 是我所知道的最好的。对于你的具体问题,我很肯定这是你最快的路线。其他的paxos实现也在附近,它也可能在网络冗余虚拟IP工具上构建一些东西,比如 Wackamole . 我相信大多数商业数据库的高端版本都提供仲裁功能作为一种(昂贵的)选择。

    此外,对于许多应用程序来说,稍微降低正确性或调整问题以允许更简单的解决方案是可以接受的。

    例如,如果一个单一的故障点是可以容忍的,因为恢复可能很快,那么问题就很小:只需要一个特殊的节点来完成工作。

    另一种方法可能是围绕等量操作构建系统,因此可以容忍重复处理。

    最后,您可以将工作负载划分到一个非冗余系统池中:在这里,故障将延迟处理,直到恢复,但仅限于该节点上的项目,而不是整个工作负载。

    这些妥协是如此简单,往往是一个更好的选择。我们必须权衡完整解决方案的效用与实现它的复杂性,看看是否真的有价值。这就是为什么这么多实际系统只使用 2 Phase 3 Phase Commit 尽管它们在某些情况下会阻塞:与完全仲裁系统的复杂性相比,可用性的降低是可以容忍的。

        2
  •  1
  •   clemahieu    16 年前

    我不清楚在酒吧发短信。

    如果他们从外部源获取某种类型的工作对象,而您只希望其中一个对象处理这些工作,则可以使用哈希值空间2^64,将该空间除以每个节点获取块的节点数。每个节点可以在工作对象进入时散列它们,并确定它是否是它们的。

        3
  •  0
  •   Thomas    16 年前

    看看路由协议(OSPF和IS-IS)是如何做到这一点的,看看这是否适合您。他们选举一名领导人(在OSPF的情况下,选举一名后备领导人)。