12

我一直想知道为什么 ZooKeeper 需要集成中的大多数机器才能工作。假设我们有一个非常简单的 3 台机器集合 - A、B、C。

当 A 失败时,会选出新的领导者——很好,一切正常。当另一个人死了,比如说B,服务不可用。是否有意义?为什么机器 C 不能单独处理所有事情,直到 A 和 B 再次启动?

由于一台机器足以完成所有工作(例如单机合奏工作正常)......

ZooKeeper 以这种方式设计有什么特别的原因吗?有没有办法配置 ZooKeeper,例如,当 N 中的至少一个启动时,集成始终可用?

编辑: 也许有一种方法可以应用自定义的领导者选择算法?或者定义法定人数?

提前致谢。

4

3 回答 3

11

Zookeeper 旨在可靠地分发事物。如果系统网络变得分段,那么您不希望两部分独立运行并可能不同步,因为当故障解决时,它不知道该做什么。如果它在不到多数的情况下拒绝运行,那么您可以放心,当故障解决后,一切都会恢复正常,无需进一步干预。

于 2013-04-17T13:04:31.343 回答
8

获得多数票的原因是为了避免所谓的“脑裂”问题。

基本上在网络故障中,您不希望系统的两个部分像往常一样继续。您希望一个继续,另一个了解它不是集群的一部分。

实现这一目标的主要方法有两种,一种是持有共享资源,例如领导者持有锁的共享磁盘,如果你能看到锁,你就是集群的一部分,如果你没有,你就退出了。如果你拿着锁,你就是领导者,如果你没有,你就不是。这种方法的问题是您需要该共享资源。

防止脑裂的另一种方法是多数票,如果您获得足够的选票,您就是领导者。这仍然适用于两个节点(法定人数为 3),其中领导者说它是领导者,而充当“见证人”的另一个节点也同意。这种方法更可取,因为它可以在无共享架构中工作,而这正是 Zookeeper 使用的

正如迈克尔所提到的,一个节点无法知道它看不到集群中其他节点的原因是因为这些节点已关闭还是存在网络问题 - 安全的赌注是说没有仲裁。

于 2013-04-19T19:37:08.300 回答
1

让我们看一个示例,该示例说明如果法定人数(正在运行的服务器的大多数)太小,事情会如何出错。

假设我们有五台服务器,法定人数可以是任何两台服务器的集合。现在假设服务器 s1 和 s2 承认他们已经复制了创建 znode /z 的请求。服务返回给客户端说 znode 已经创建。现在假设服务器 s1 和 s2 在有机会将新的 znode 复制到其他服务器之前,与其他服务器和客户端分开了任意长的时间。处于这种状态的服务能够取得进展,因为有三台服务器可用,根据我们的假设实际上只需要两台,但这三台服务器从未见过新的 znode /z。因此,创建 /z 的请求是不持久的。

这是脑裂场景的一个例子。为避免此问题,在此示例中,仲裁的大小必须至少为 3,这是 ensemble 中五台服务器中的多数。为了取得进展,整体需要至少三台可用的服务器。为了确认更新状态的请求已成功完成,该集成还要求至少三台服务器确认它们已复制它。

于 2017-07-06T10:23:28.820 回答