天天看点

《ZooKeeper:分布式过程协同技术详解》——2.4 一个主-从模式例子的实现

本节书摘来自华章计算机《zookeeper:分布式过程协同技术详解》一书中的第2章,第2.4节,作者:flavio junqueira, benjamin reed 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

本节中我们通过zkcli工具来实现主-从示例的一些功能。这个例子仅用于教学目的,我们不推荐使用zkcli工具来搭建系统。使用zkcli的目的仅仅是为了说明如何通过zookeeper来实现协作菜谱,从而撇开在实际实现中所需的大量细节。我们将在下一章中进入实现的细节。

主-从模式的模型中包括三个角色:

主节点

主节点负责监视新的从节点和任务,分配任务给可用的从节点。

从节点

从节点会通过系统注册自己,以确保主节点看到它们可以执行任务,然后开始监视新任务。

客户端

客户端创建新任务并等待系统的响应。

现在探讨这些不同的角色以及每个角色需要执行的确切步骤。

2.4.1 主节点角色

因为只有一个进程会成为主节点,所以一个进程成为zookeeper的主节点后必须锁定管理权。为此,进程需要创建一个临时znode,名为/master:

刚刚发生了什么?首先创建一个临时znode /master。我们在znode中添加了主机信息,以便zookeeper外部的其他进程需要与它通信。添加主机信息并不是必需的,但这样做仅仅是为了说明我们可以在需要时添加数据。为了设置znode为临时性的,需要添加-e标志。记得,一个临时节点会在会话过期或关闭时自动被删除。

现在让我们看下我们使用两个进程来获得主节点角色的情况,尽管在任何时刻最多只能有一个活动的主节点,其他进程将成为备份主节点。假如其他进程不知道已经有一个主节点被选举出来,并尝试创建一个/master节点。让我们看看会发生什么:

zookeeper告诉我们一个/master节点已经存在。这样,第二个进程就知道已经存在一个主节点。然而,一个活动的主节点可能会崩溃,备份主节点需要接替活动主节点的角色。为了检测到这些,需要在/master节点上设置一个监视点,操作如下:

stat命令可以得到一个znode节点的属性,并允许我们在已经存在的znode节点上设置监视点。通过在路径后面设置参数true来添加监视点。当活动的主节点崩溃时,我们会观察到以下情况:

在输出的最后,我们注意到nodedeleted事件。这个事件指出活动主节点的会话已经关闭或过期。同时注意,/master节点已经不存在了。现在备份主节点通过再次创建

/master节点来成为活动主节点。

因为备份主节点成功创建了/master节点,所以现在客户端开始成为活动主节点。

2.4.2 从节点、任务和分配

在我们讨论从节点和客户端所采取的步骤之前,让我们先创建三个重要的父znode,

这三个新的znode为持久性节点,且不包含任何数据。本例中,通过使用这些znode可以告诉我们哪个从节点当前有效,还告诉我们当前有任务需要分配,并向从节点分配任务。

在真实的应用中,这些znode可能由主进程在分配任务前创建,也可能由一个引导程序创建,不管这些节点是如何创建的,一旦这些节点存在了,主节点就需要监视

/workers和/tasks的子节点的变化情况:

请注意,在主节点上调用stat命令前,我们使用可选的true参数调用ls命令。通过true这个参数,可以设置对应znode的子节点变化的监视点。

2.4.3 从节点角色

从节点首先要通知主节点,告知从节点可以执行任务。从节点通过在/workers子节点下创建临时性的znode来进行通知,并在子节点中使用主机名来标识自己:

注意,输出中,zookeeper确认znode已经创建。之前主节点已经监视了/workers的子节点变化情况。一旦从节点在/workers下创建了一个znode,主节点就会观察到以下通知信息:

watcher::

下一步,从节点需要创建一个父znode/assing/worker1.example.com来接收任务分配,并通过第二个参数为true的ls命令来监视这个节点的变化,以便等待新的任务。

从节点现在已经准备就绪,可以接收任务分配。之后,我们通过讨论客户端角色来看一下任务分配的问题。

2.4.4 客户端角色

客户端向系统中添加任务。在本示例中具体任务是什么并不重要,我们假设客户端请求主从系统来运行cmd命令。为了向系统添加一个任务,客户端执行以下操作:

我们需要按照任务添加的顺序来添加znode,其本质上为一个队列。客户端现在必须等待任务执行完毕。执行任务的从节点将任务执行完毕后,会创建一个znode来表示任务状态。客户端通过查看任务状态的znode是否创建来确定任务是否执行完毕,因此客户端需要监视状态znode的创建事件:

执行任务的从节点会在/tasks/task-0000000000节点下创建状态znode节点,所以我们需要用ls命令来监视/tasks/task-0000000000的子节点。

一旦创建任务的znode,主节点会观察到以下事件:

主节点之后会检查这个新的任务,获取可用的从节点列表,之后分配这个任务给worker1.example.com:

从节点接收到新任务分配的通知:

从节点之后便开始检查新任务,并确认该任务是否分配给自己:

一旦从节点完成任务的执行,它就会在/tasks中添加一个状态znode:

之后,客户端接收到通知,并检查执行结果:

客户端检查状态znode的信息,并确认任务的执行结果。本例中,我们看到任务成功执行,其状态为“done”。当然任务也可能非常复杂,甚至涉及另一个分布式系统。最终不管是什么样的任务,执行任务的机制与通过zookeeper来传递结果,本质上都是一样的。

继续阅读