我一直想知道为什么ZooKeeper需要合奏中的大多数机器才能工作。让我们说我们有一个非常简单的3台机器的集合 - A,B,C。
当A失败时,新领导人当选 - 很好,一切正常。当另一个人死亡时,让我们说B,服务不可用。是否有意义?为什么机器C不能单独处理所有事情,直到A和B再次启动?
由于一台机器足以完成所有工作(例如单机组合工作正常)......
ZooKeeper以这种方式设计有什么特别的原因吗?有没有办法配置ZooKeeper,例如当N中的至少一个出现时,整体是否可用?
修改 也许有一种方法可以应用领导者选择的自定义算法?或者定义法定人数的大小?
提前致谢。
答案 0 :(得分:9)
Zookeeper旨在可靠地分发内容。如果系统网络变得分段,那么您不希望这两个半部分独立运行并且可能不同步,因为当故障解决时,它将不知道该怎么做。如果你在低于大多数时拒绝操作,那么你可以放心,当失败得到解决时,一切都会在没有进一步干预的情况下立即恢复。
答案 1 :(得分:6)
获得多数票的原因是为了避免称为“裂脑”的问题。
基本上在网络故障中,您不希望系统的两个部分像往常一样继续。你希望一个人继续,另一个人知道它不是集群的一部分。
有两种主要方法可以实现,即持有共享资源,例如领导者持有锁的共享磁盘,如果你不知道,你可以看到你是群集的一部分退出如果你持有锁,你就是领导者,如果你不是,那你就不是。这种方法的问题在于您需要该共享资源。
防止裂脑的另一种方法是大多数人,如果你获得足够的选票,你就是领导者。这仍然适用于两个节点(法定数量为3),其中领导者表示它是领导者而另一个节点充当“见证人”也同意。这种方法是可取的,因为它可以在无共享架构中工作,实际上这就是Zookeeper使用的
正如Michael所提到的,一个节点无法知道它没有看到集群中其他节点的原因是因为这些节点是关闭还是存在网络问题 - 可以肯定的是,没有法定人数。
答案 2 :(得分:1)
让我们看一个示例,该示例显示如果仲裁(大多数正在运行的服务器)太小,事情可能会出错。
假设我们有五台服务器,仲裁可以是两台服务器。现在说服务器s1和s2确认他们已经复制了创建znode / z的请求。该服务返回给客户端,表示已创建znode。现在假设服务器s1和s2在有机会将新的znode复制到其他服务器之前,与其他服务器和客户端分开一段任意长的时间。处于此状态的服务能够取得进展,因为有三个服务器可用,并且根据我们的假设它实际上只需要两个,但这三个服务器从未见过新的znode / z。因此,创建/ z的请求不是持久的。
这是裂脑情景的一个例子。为避免此问题,在此示例中,仲裁的大小必须至少为3,这是整体中五个服务器中的大多数。为了取得进展,整体需要至少三台服务器。为了确认更新状态的请求已成功完成,此集合还要求至少三台服务器确认已复制它。