ZooKeeper的典型应用场景——分布式队列

分布式队列,简单地分为两大类,一种是常规的先入先出队列,另一种则是要等到队列元素聚集之后,才统一安排执行的Barrier模型。

先入先出

利用ZooKeeper实现FIFO队列,和分布式共享锁的实现十分类似,可以说是更为简单。FIFO队列类似于每个操作都是写的共享锁模型,设计思路:所有客户端都会到/queue_info这个节点下面创建一个临时顺序节点,例如“/queue_info/[hotst-name]-00002”。

创建完节点之后,根据如下4个步骤来执行:

  • 通过调用getChildren()接口来确定获取/queue_info节点下的所有子节点,即获取队列中所有的元素
  • 确定自己的节点在所有子节点中的顺序
  • 如果自己不是最小的子节点,那么就需要进入等待,同时向比自己序号小的最后一个节点注册Watcher监听
  • 接到Watcher通知后,重复步骤1

Barrier:分布式屏障

在分布式系统中,屏障特指系统中的一个协调条件,规定了一个队列的元素必须都聚集之后,才能统一进行安排,否则一直等待。这往往出现在那些大规模分布式并行计算的应用场景上:最终的合并计算需要很多并行计算的子结果来进行。
基于Barrier的分布式队列其实是在FIFO队列的基础上进行了增加,大致的设计思想如下:开始时,/queue_info节点是一个已经存在的默认节点,并且将其节点的数据内容赋值为一个数字n来表示Barrier值,例如n=10表示只有当/queue_info节点下的子节点个数达到10后,才会打开Barrier。之后,所有的客户端都会到/queue_info节点下创建一个临时节点/queue_info/[hostname]。

在创建完/queue_barrier节点之后,根据如下5个步骤来确定执行顺序。

  • 通过调用getData()接口获取/queue_barrier节点的数据内容:10
  • 通过调用getChildren()接口获取/queue_barrier节点下的所有子节点,即获取队列中的所有元素,同时注册对子节点列表变更的Watcher监听
  • 统计子节点的个数,如果不足10,需要进入等待,否则执行业务逻辑
  • 在等待期间,接收到Wacher通知后,重复步骤2

猜你喜欢

转载自blog.csdn.net/pierce_liu/article/details/80560012