如何在任何MQ平台中实现此单一并发分布式队列?

时间:2017-02-01 12:08:08

标签: redis queue message-queue amazon-sqs

我目前很难找到实现特定类型队列的解决方案,这需要以下特征:

  1. 所有队列必须遵守添加作业的顺序。
  2. 整个队列的并发度为1,这意味着每个队列一次只能执行一个作业,而不是工作者。
  3. 这样会有超过几千个队列。
  4. 需要分发并能够扩展(例如,如果我添加一个工人)
  5. 基本上它是一个单进程FIFO队列,这正是我在尝试不同的消息队列软件(如ActiveMQ或RabbitMQ)时所需要的,但是只要我将它扩展为2个工作者,它就不起作用,因为在这种情况下我希望它能够扩展和维护单个进程队列的完全相同的功能。下面我将附上如何在具有多个worker的分布式环境中工作的描述。

    拓扑结构的示例:(请注意,队列工作人员之间存在多对多的关系)

    Distributed FIFO Queue

    如何运行的示例:

    +------+-----------------+-----------------+-----------------+
    | Step | Worker 1        | Worker 2        | Worker 3        |
    +------+-----------------+-----------------+-----------------+
    | 1    | Fetch Q/1/Job/1 | Fetch Q/2/Job/1 | Waiting         |
    +------+-----------------+-----------------+-----------------+
    | 2    | Running         | Running         | Waiting         |
    +------+-----------------+-----------------+-----------------+
    | 3    | Running         | Done Q/2/Job/1  | Fetch Q/2/Job/2 |
    +------+-----------------+-----------------+-----------------+
    | 4    | Done Q/1/Job/1  | Fetch Q/1/Job/2 | Running         |
    +------+-----------------+-----------------+-----------------+
    | 5    | Waiting         | Running         | Running         |
    +------+-----------------+-----------------+-----------------+
    

    可能这不是最好的表示,但它表明即使在队列1 队列2 中,也有更多的工作,但工人3确实在上一个工作完成之前不会开始提取下一个工作。

    这是我努力寻找一个好的解决方案。

    我尝试了很多其他的解决方案,比如rabbitMQ,activeMQ,apollo ...这些允许我创建数千个队列,但是当我尝试时,所有队列都将使用worker 3来运行队列中的下一个作业。并发性是每个工作者

    是否有任何解决方案可以在任何MQ平台中实现这一点,例如ActiveMQ,RabbitMQ,ZeroMQ等。?

    谢谢:)

1 个答案:

答案 0 :(得分:2)

您可以使用Redis列表以及所有工作人员BRPOP为其工作添加的“调度”队列来实现此目的。调度队列中的每个作业都标记有原始队列ID,当工作者完成作业后,它将转到此原始队列并执行RPOPLPUSH到调度队列,以使下一个作业可用于任何其他工作。因此,调度队列最多具有 num_queues 元素。

您必须处理的一件事是源队列为空时调度队列的初始填充。这可能只是发布者针对最初设置的每个队列的“空”标志进行的检查,并且当原始队列中没有任何内容留下以进行分派时也由工作者设置。如果设置了此标志,则发布者只需将第一个作业LPUSH直接发送到调度队列。