Zookeeper应用场景之分布式队列

  |   0 评论   |   0 浏览

业界存在不少消息中间件产品,实现各不相同。这篇文章主要介绍基于ZooKeeper实现的分布式队列。分布式队列,简单来说分为两大类,一种是常规的先入先出队列,另一种是要等到所有元素集聚之后才能统一安排执行的Barrier模型。

1. FIFO:先入先出

FIFO队列是一种非常典型的按序执行的队列模型:先进入队列的请求操作完成后,才会开始处理后面的请求。

使用zk实现FIFO队列,和zk对于共享锁的实现类似。FIFO队列就类似于一个全局的共享锁模型。所有客户端都会到一个节点(比如queue_fifo)下创建一个临时顺序节点。
jiedian
创建完节点,根据如下四个步骤确定执行顺序。

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

整个通过流程如下图所示:

工作流程示意图

2. Barrier:分布式屏障

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

示意图

创建完节点后,接下来的流程为:

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

整个Barrier队列的工作流程如下:
gongzuo

来自《从paxos到zookeeper 分布式一致性原理与实战》,稍微进行了归纳总结。


标题:Zookeeper应用场景之分布式队列
作者:guobing
地址:http://www.guobingwei.tech/articles/2019/03/10/1552174587401.html