ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它是一个为分布式应用提供一~致性服务的软件,所提供的功能包括:配置维护、域名服务、分布式同步、组服务等。下面我们介绍一下典型的分布式环境下遇到的一些典型问题的解决办法。
1.集群管理(Group Membership)
ZooKeeper能够很容易地实现集群管理的功能,如图1.15所示。如果多台Server组成一个服务集群,那么必须有一个“总管”知道当前集群中每台机器的服务状态,一旦有机器不能提供服务,就必须知会集群中的其他集群,并重新分配服务策略。同样,当集群的服务能力增加时,就会增加一台或多台Server, 这些也必须让“总管”知道。
Zo0 Keeper不仅能够维护当前集群中机器的服务状态,而且能够选出一个“总管”,让“总管”来管理集群一这就是 Zookeeper I的另一个功能 Leader Election。
它的实现方式是在 Zookeeper上创建一个 EPHEMERAL类型的目录节点,然后每个 Server在它们创建目录节点的父目录节点上调用 getchildrenf String path, Boolean watch)方法并设置 watch为true。由于是 EPHEMERAL目录节点,当创建它的 Server死去时,这个目录节点也随之被删除,所以 Children将会变化;这时 get Children上的Watch将会被调用,通知其他 Server某台 Server已死了。新增 Server也是同样的原理。
那么,Z0 Keeper如何实现 Leader Election,也就是选出一个 Master Server呢?和前面的一样,每台 Server创建一个 EPHIEMERAL目录节点,不同的是它还是一个SEQUENTIAL目录节点,所以它是个 EPHEMERAL SEQUENTIAL目录节点。之所以它是 EPHEMERAL SEQUENTIAL目录节点,是因为我们可以给每台 Server g编号。
我们可以选择当前最小编号的 Server为 Master,假如这个最小编号的 Server死去,由于它是 EPHEMERAL节点,死去的 Server对应的节点也被删除,所以在当前的节点列表中又出现一个最小编号的节点,我们就选择这个节点为当前 Master。这样就实现了动态选择 Master,避免传统上单 Master容易出现的单点故障问题。
2.共享锁( Locks)
在同一个进程中,共享锁很容易实现,但是在跨进程或者不同 Server的情况下就不好实现了。然而 Zookeeper能很容易地实现这个功能,它的实现方式也是通过获得锁的 Server创建一个 EPHEMERAL SEQUENTIAL目录节点,再通过调用 getchildren方法,查询当前的目录节点列表中最小的目录节点是否是自己创建的目录节点,如果是自己创建的,那么它就获得了这个锁;如果不是,那么它就调用 exists(String path,Boolean watch)方法,并监控 Zookeeper上目录节点列表的变化,直到使自己创建的节点是列表中最小编号的目录节点,从而获得锁。释放锁很简单,只要删除前面它自己所创建的目录节点即可。
3.队列管理
Keener可以外理以下两种型的队列
其一,同步队列。即当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
其二,队列按照FIFO方式进行入队和出队操作,例如实现生产者和消费者模型。用Zo0 Keeper实现同步队列的实现思路如下。
创建一个父目录/ synchronizing,每个成员都监控标志( Set Watch)位目录/ synchronizing/start是否存在,然后每个成员都加人这个队列;
加人队列的方式就是创建 /synchronizing/member i的临时目录节点,之后每个成员获取/ synchronizing目录的所有目录节点,也就是 member_i;?判断i的值是否已经是成员的个数,如果小于成员个数等待/ 'synchronizing/ start的出现,如果已经相等就创建 /synchronizing/star。
用 Zookeeper实现FIFO队列的思路如下。
在特定的网站制作目录下创建 SEQUENTIAL类型的子目录 queue I,这样就能保证所有成员加入队列时都是有编号的;出队列时通过 get Children()方法返回当前所有队列中元素,再消费其中最小的一个,这样就能保证FIFO。
本文地址://qlpinke.com//article/4458.html