Zookeeper基础(06)主从模式示例

下面我们通过zkCli⼯具来实现主-从⽰例的⼀些功能。这个例⼦仅⽤于学习测试,我们不推荐使⽤zkCli⼯具来搭建系统。使⽤zkCli的⽬的仅仅是为了说明如何通过ZooKeeper来实现协作,从⽽撇开在实际实现中所需的⼤量细节。

主-从模式的模型中包括三个⾓⾊:

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

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

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

现在探讨这些不同的⾓⾊以及每个⾓⾊需要执⾏的确切步骤。



主节点角色

首先启动zookeeper,

Zookeeper基础(06)主从模式示例_第1张图片

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

Zookeeper基础(06)主从模式示例_第2张图片

①  创建主节点的znode,以便获得管理权。使用-e标志来表示创建的znode为临时性的。

②  列出ZooKeeper树的根。

③  获取/master znode的元数据和数据。

来看一下上面的操作,⾸先创建⼀个临时znode/master。我们在znode中添加了主节点主机信息,以便ZooKeeper外部的其他进程需要与它通信。添加主机信息并不是必需的,但这样做仅仅是为了说明我们可以在需要时添加数据。为了设置znode为临时性的,需要添加-e标志。记得,⼀个临时节点会在会话过期或关闭时⾃动被删除。

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

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

Zookeeper基础(06)主从模式示例_第3张图片

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

Zookeeper基础(06)主从模式示例_第4张图片

在输出的最后,我们注意到NodeDeleted事件。这个事件指出活动主节点的会话已经关闭或过期。同时注意,/master节点已经不存在了。现在备份主节点通过再次创建/master节点来成为活动主节点(第二个客户端操作):

Zookeeper基础(06)主从模式示例_第5张图片

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






从节点、任务和分配

在我们讨论从节点和客户端所采取的步骤之前,让我们先创建三个重要的⽗znode,/workers、/tasks和/assign:

Zookeeper基础(06)主从模式示例_第6张图片

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

在真实的应⽤中,这些znode可能由主进程在分配任务前创建,也可能由⼀个引导程序创建,不管这些节点是如何创建的,⼀旦这些节点存在了,主节点就需要监视/workers和/tasks的⼦节点的变化情况:

Zookeeper基础(06)主从模式示例_第7张图片

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






从节点角色

从节点⾸先要通知主节点,告知从节点可以执⾏任务。从节点通过在/workers⼦节点下创建临时性的znode来进⾏通知,并在⼦节点中使⽤主机名来标识⾃⼰:

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

Zookeeper基础(06)主从模式示例_第8张图片

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


Zookeeper基础(06)主从模式示例_第9张图片

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





客户端角色

客户端向系统中添加任务。在本⽰例中具体任务是什么并不重要,我们假设客户端请求主从系统来运⾏cmd命令。为了向系统添加⼀个任务,客户端执⾏以下操作(打开第三个客户端):

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

Zookeeper基础(06)主从模式示例_第10张图片

执⾏任务的从节点会在/tasks/task-0000000000节点下创建状态znode节点,所以我们需要⽤ls命令来监视/tasks/task-0000000000的⼦节点。⼀旦创建任务的znode,主节点会观察到以下事件:

Zookeeper基础(06)主从模式示例_第11张图片

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

Zookeeper基础(06)主从模式示例_第12张图片

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

Zookeeper基础(06)主从模式示例_第13张图片

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

Zookeeper基础(06)主从模式示例_第14张图片

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

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

检查结果:

Zookeeper基础(06)主从模式示例_第15张图片


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



我们的交流基地,“JAVA互联网技术交流:789650498”欢迎小伙伴们一起来交流:

Zookeeper基础(06)主从模式示例_第16张图片

你可能感兴趣的:(Zookeeper基础(06)主从模式示例)