仲裁模式下,Zookeeper在集合中所有服务器上复制它的数据树。但是如果一个客户端不得不等每个服务器存储完数据才能继续运行的话,那延迟是不可接受的。在公共管理中,法定人数要求最少数量的立法者出席进行投票。而在zookeeper中,为了让其能工作,法定人数是需要最少数量正常运行的服务器。告诉客户端数据已经被安全存储之前,Zookeeper需要最少的服务器需存储客户端的数据。比如,我们一共有五台Zookeeper服务器,但是法定人数就是三台。只要任意三台服务器存储了数据,客户端就可以继续运行,另外两台服务器最终会追赶上来并存储数据。

    为仲裁模式选定足够的服务器是很重要的。无论系统延迟和奔溃,仲裁者必须保证任何的更新请求Zookeeper都会积极的响应并保存,直到另外一个请求取代它。

    为了理解其中的意义,让我们来通过一个例子来说明如果仲裁者过少会引起什么样的问题。比如说我们有五台服务器,仲裁者可以是其中任意的两台。现在服务器s1和s2说它们已经复制了创建\/z节点的请求。然后Zookeeper告诉客户端节点已经创建好了。现在假设这两台服务器在它们有机会复制新增的节点到其它服务器之前,因为网络分区的原因与其它服务器和客户端隔离任意长的时间。在这种状态下,Zookeeper服务能继续运行因为还有其它三台服务器可用,实际上根据我们的假设只需要两台服务器就可以了,但是这三台服务器都不知道创建了\/z的节点。自然,创建\/z节点的请求没有持久化。

    这个例子就是在第一章提到过的脑裂场景之一。为了避免这个问题,这个例子中仲裁者的数量不得低于三个,这是五台服务器的大多数。为了继续运行,整个Zookeeper集合必须保证三台服务器可用。为了确认更新请求已经成功的完成了,Zookeeper集合需要至少三台服务器承认它们已经复制了这个状态。当然,如果Zookeeper集合想要继续运行,那么每个更新操作都要成功的完成,我们至少需要一台包含了更新操作副本的服务器可用(也就是说,仲裁者至少要有一台)。

    采用这样一种架构,我们能容忍f台服务器的宕机,f小于总服务器数的一半。比如说,我们有5台服务器,那么最多能忍受2台服务器宕机。服务器的数量不能强制设为奇数的话,偶数会使得系统更加脆弱。举例来说我们有4台服务器,那么大多数就意味着3台服务器。然而,系统只能容忍1台服务器宕机,因为2台宕机使得系统就没有了大多数服务器。结果就是,4台服务器只允许一台服务器宕机,但是仲裁者相比之下就更多了,这意味着我们要得到更多确认来处理每个请求。底线是我们应该总数设置奇数台服务器。

    我们可以设置仲裁者数量不同于大多数,当时这将会在更高级的章节进行讨论。我们会在第十章讨论。