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

        业界有不少分布式队列产品,不过绝大多数都是类似于ActiveMQ、Metamorphosis、Kafka和HornetQ等的消息中间件(或称为消息队列)。在这里,我们主要介绍基于ZooKeeper实现的分布式队列。分布式队列,简单的讲分为两大类,一种是常规的先入先出队列,另一种则是要等到队列元素聚集之后才统一安排执行的Barrier模型。

FIFO:先入先出

        FIFO(First Input First Output,先入先出)的算法思想,以其简单明了的特点,广泛应用于计算机科学的各个方面。而FIFO队列也是一种非常典型且应用广泛的按序执行的队列模型:先进入队列的请求操作先完成后,才会开始处理后面的请求。

        使用ZooKeeper实现FIFO队列,和共享锁的实现非常类似。FIFO队列就类似于一个全写的共享锁模型,大体的设计思路其实非常简单:所有客户端都会到/queue_fifo这个节点下面创建一个临时顺序节点,例如/queue_fifo/192.168.0.1-0000000001,如下图所示。

ZooKeeper的典型应用场景之分布式队列。_第1张图片

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

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

        整个FIFO队列的工作流程,可以用下图来表示。

ZooKeeper的典型应用场景之分布式队列。_第2张图片

Barrier:分布式屏障

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

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

  1. 通过调用getData()接口获取/queue_barrier节点的数据内容:10.
  2. 通过调用getChildren()接口获取/queue_barrier节点下的所有子节点,即获取队列中的所有元素,同时注册对子节点列表变更的Watcher监听。
  3. 统计子节点的个数。
  4. 如果子节点个数还不足10个,那么就需要进入等待。
  5. 接收到Watcher通知后,重复步骤2.

        整个Barrier队列的工作流程,可以用下图表示。

ZooKeeper的典型应用场景之分布式队列。_第3张图片

你可能感兴趣的:(#,zookeeper,分布式)