ZooKeeper 观察者
观察者:在不损害写入性能的情况下扩展 ZooKeeper
虽然 ZooKeeper 通过让客户端直接连接到集合的投票成员来表现得很好,但这种架构使得很难扩展到大量的客户端。问题在于,随着我们添加更多投票成员,写入性能下降。这是因为写入操作需要集合中至少一半节点(通常)的同意,因此随着添加更多投票者,投票的成本可能会大幅增加。
我们引入了一种称为观察者的新型 ZooKeeper 节点,它有助于解决此问题并进一步提高 ZooKeeper 的可扩展性。观察者是集合的非投票成员,它们只听到投票结果,而不是导致投票结果的协议。除了这个简单的区别之外,观察者的功能与跟随者完全相同——客户端可以连接到它们并向它们发送读写请求。观察者将这些请求转发给领导者,就像跟随者所做的那样,但随后它们只需等待听到投票结果。因此,我们可以根据需要增加观察者的数量,而不会损害投票的性能。
观察者还有其他优点。因为它们不投票,所以它们不是 ZooKeeper 集合的关键部分。因此,它们可以发生故障或与集群断开连接,而不会损害 ZooKeeper 服务的可用性。对用户的好处是,观察者可以比跟随者通过不太可靠的网络链路进行连接。事实上,观察者可以用于与另一个数据中心的 ZooKeeper 服务器通信。观察者的客户端将看到快速的读取,因为所有读取都是本地提供的,并且写入产生的网络流量最小,因为在没有投票协议的情况下所需的消息数量更少。
如何使用观察者
设置使用观察者的 ZooKeeper 集群非常简单,只需对配置文件进行两处更改。首先,在每个将成为观察者的节点的配置文件中,您必须放置此行
peerType=observer
此行告诉 ZooKeeper 该服务器将成为观察者。其次,在每个服务器配置文件中,您必须向每个观察者的服务器定义行添加 :observer。例如
server.1:localhost:2181:3181:observer
这告诉其他每个服务器 server.1 是一个观察者,并且它们不应该期望它投票。这是您需要执行的所有配置,才能将观察者添加到您的 ZooKeeper 集群。现在,您可以连接到它,就好像它是一个普通的跟随者一样。通过运行以下命令来试用它
$ bin/zkCli.sh -server localhost:2181
其中 localhost:2181 是每个配置文件中指定的观察者的主机名和端口号。您应该会看到一个命令行提示符,通过该提示符,您可以发出诸如 ls 之类的命令来查询 ZooKeeper 服务。
如何使用观察者主服务器
观察者作为集群的非投票成员简单地发挥作用,与跟随者共享学习者界面,并且仅持有略有不同的内部管道。两者都通过法定人数端口与领导者保持连接,通过该端口他们了解集群上的所有新提案。
默认情况下,观察者通过其法定人数端口连接到法定人数的领导者,这就是他们了解集群上所有新提案的方式。允许观察者连接到跟随者而不是连接到领导者来插入提交流,这会带来好处。它将支持观察者的负担从领导者身上转移,并允许领导者专注于协调写入的提交。这意味着当领导者处于高负载下时性能会更好,特别是高网络负载,例如在领导者选举后许多学习者需要同步时。当观察者数量较多时,它会减少领导者上维护的总网络连接数。激活跟随者来支持观察者允许观察者的总数扩展到数百个。另一方面,观察者的可用性得到了提高,因为大量观察者完成同步并开始为客户端流量提供服务所需的时间更短。
此功能可以通过让集群的所有成员知道 Followers 将用来侦听 Observer 连接的端口来激活。将以下条目添加到服务器配置文件时,将指示 Observer 连接到端口 2191 上的对等方(领导者和 Follower),并指示 Follower 创建一个 ObserverMaster 线程来侦听和服务该端口。
observerMasterPort=2191
示例用例
下面列出了 Observer 的两个示例用例。事实上,无论您希望扩展 ZooKeeper 集群的客户端数量,还是希望将集群的关键部分与处理客户端请求的负载隔离开来,Observer 都是一个不错的架构选择。
- 作为数据中心桥梁:在两个数据中心之间形成 ZK 集群是一项有问题的尝试,因为数据中心之间延迟的高差异可能导致误报故障检测和分区。但是,如果集群完全在一个数据中心运行,而第二个数据中心仅运行 Observer,则分区不会出现问题,因为集群仍然保持连接。Observer 的客户端仍然可以看到并发出提议。
- 作为到消息总线的链接:一些公司表示有兴趣将 ZK 用作持久可靠的消息总线的一个组件。Observer 将为这项工作提供一个自然的集成点:可以使用插件机制将 Observer 看到的提议流附加到发布-订阅系统,同样无需加载核心集群。