生产者通过消息队列一致地对消费者进行散列?

时间:2010-09-01 20:10:13

标签: rabbitmq amqp producer-consumer consistent-hashing

我有一个生产者,我希望通过一致的散列在消费者中一致地分配工作。例如,对于消费者节点X和Y,任务A,B,C应始终转到消费者X,D,E,F应转到消费者Y.但如果Z加入消费者池,这可能会转移一点。

我不想处理编写自己的逻辑来连接到消费者节点,特别是不管理节点加入和离开池,所以我走上了使用RabbitMQ和独占队列的道路每个消费者节点。

我遇到的一个问题是列出这些队列,因为生产者需要在分配工作之前知道所有可用的队列。 AMQP甚至不支持列表队列,这使我不确定我的整个方法。 RabbitMQ和Alice(brokenly at the moment)添加了该功能:Is there an API for listing queues and exchanges on RabbitMQ?

这是明智的使用兔子吗?我应该使用消息队列吗?是否有更好的设计,因此队列可以始终将我的工作分配给消费者,而不是我需要这样做?

2 个答案:

答案 0 :(得分:6)

您所描述的内容可以在RabbitMQ中使用。

您的设置将类似于:

  • 制作人将消息发布到主题交换;我们将其命名为consistent_divider;
  • 当一个消费者加入池时,它连接到代理并使用其名称创建一个独占队列,但不会将其绑定到任何内容
  • 制作人定期轮询经纪人(可能使用rabbitmqctl list_consumers)来检查消费者是否已经改变;如果有,则删除所有现有绑定并根据需要重新绑定队列;
  • 当生产者发布时,会为消息分配与其任务类型匹配的路由密钥。

因此,如果你有6种任务类型:A,B,C,D,E,F,只有两个消费者C1和C2,你的绑定看起来像:C1绑定3次到使用路由键A,B的consistent_divider和C; C2使用路由密钥D,E和F绑定3次到c_d。

当C3加入池时,生产者会看到这一点并相应地重新绑定队列。

当生产者发布时,它会发送带有routing_keys A,B,C,D,E和/或F的消息,消息将被路由到正确的队列。

这有两个潜在的问题:

  1. 消费者加入游戏池并将消息路由到游戏池之间存在轻微的延迟;另外,如果队列中已经存在消息,则消费者可能获得针对另一个消费者的消息(例如,C3连接,生产者重新绑定,但C2仍然会获得一些E和F消息,因为它们已经在其队列中),
  2. 如果消费者因任何原因死亡,其队列中的消息(以及到其队列的路由)将会丢失;这可以通过分别重新发布和解密消息来解决。
  3. 要回答你的上一个问题,你可能想要使用排队,而RabbitMQ是一个很好的选择,但是你的要求(更确切地说是“一致地划分工作”)并不完全适合AMQP。

答案 1 :(得分:0)

您可以将Rabbitmq的官方consistent-hashing插件用作已回答的here