【问题标题】:Connecting multiple producers and multiple consumers using FIFO AWS SQS with message group ids使用带有消息组 ID 的 FIFO AWS SQS 连接多个生产者和多个消费者
【发布时间】:2020-10-21 07:00:50
【问题描述】:

假设我们有一个 AWS FIFO SQS 队列和两个消息生产者 A 和 B。每条消息都使用与生产者名称相同的组 ID 发送。换句话说,生产者 A 将组 ID“A”添加到每个消息,生产者 B 将组 ID“B”添加到每个消息。我们还有 3 个消费者 X、Y 和 Z 使用可见性超时的消息。假设队列中有 5 条消息——来自生产者 A 的三条消息和来自生产者 B 的两条消息。See the following image

考虑到给定的条件,我们将有以下工作流程:

其中一个消费者,例如 X,从队列中接收组 id 为 B 的消息 1,这使得该消息和组 B 的所有其他消息不可见,直到消息 1 被处理并从队列中删除。

然后另一个消费者,例如 Y,接收到组 id 为 A 的消息 2,这使得消息 2 和组 A 的所有其他消息不可见,直到消息 2 被处理并从队列中删除。

现在我们让消费者 Z 无法消费任何消息,因为组 A 被处理的消息 2 阻塞,组 B 被处理的消息 1 阻塞。

是否有一种技术允许消费者 Z 在给定情况下使用队列中的下一条消息?

更新 1:为什么我使用 FIFO 队列和组 ID?

假设生产者 A 和 B 代表两个用户,并且使用简单队列而不是 FIFO。消息也没有附加组 ID。

假设生产者 A 向队列发送了 100 条消息,然后生产者 B 也只向队列发送了一条消息。生产者 B 的这一条消息必须等到 A 的所有消息都处理完,这不好。我们需要在 A 和 B 的消息之间进行负载平衡,尽管 A 有一百条消息,而 B 只有一条。

为此,让我们尝试添加组 ID,因为只有 FIFO 队列支持它们,我们必须用 FIFO 替换 Simple Queue。现在上述问题解决了。当任何生产者的 A 消息在飞行中时,其中一个消费者将收到生产者 B 的消息,即使该消息在队列的后面。我们现在在 A 和 B 之间进行负载平衡。

但是,当所有组都有消息在传输中时(在这种情况下队列看起来是空的),问题就出现了,但是我们现在有更多可用的消费者无法工作,这也不是太好。

更新 2:建议的可能解决方案。

每个生产者有多个组 ID

假设我们有 10 个消费者和只有一个生产者 A。让我们将 1 到 10 的数字添加到每个消息组 id 加上一些唯一的 id,如果 10 条消息代表一个批次,那么我们将有组 id "A1- batch1""A2-batch1""A3-batch1" 以此类推,直到 "A10-batch1"。如果生产者 A 有更多消息,我们会增加批号并为另外 10 个生成组 ID,然后再为另外 10 个生成组 ID。现在每个消费者都保证收到一条消息,这很棒。但是如果生产者 B 现在发送一条消息,那么生产者 A 和 B 之间的余额比在最坏的情况下将是 10 比 1,这不是很好。此外,消费者可以横向扩展,因此生产者必须知道当前消费者的大致数量。

每个生产者的单独队列

生产者是当前使用该服务的用户。当用户连接到服务并通知消费者添加的队列时,我们必须创建一个简单队列。消费者必须连续提取每个当前存在的队列,并且即使有消息在传输中也应该能够接收新消息。在这种情况下,负载平衡很好。此解决方案增加了架构的复杂性,但应该可以工作。除非我错过了一些技术限制。

【问题讨论】:

  • 如果您想获取与当前正在发送的消息具有相同组 ID 的另一条消息,可能会导致具有相同组 ID 的消息被乱序处理。那么为什么要使用 FIFO 队列呢?
  • 感谢您的回复。我更新了问题,解释了为什么要使用 FIFO 队列。希望它能解释我的逻辑。
  • 您是否只有 2 个生产者和 3 个以上的消费者?或者你将来可能会有更多的制作人?如果生产者是“客户”,那么您当前的方法是完全可以接受的,但目前只有 2 个生产者。如果生产者超过 2 个,则不会出现这种“阻塞”行为。
  • 2 个生产者和 3 个消费者是为了解释的简单。可以有任意数量的生产者和接收者,有时生产者的数量会少于消费者。 FIFO 阻塞行为不允许一次处理来自一个生产者的多条消息,并且简单队列缺少组 ID。我的印象是,我的案子应该很常见,因此可以由不妥协的人解决。
  • 您的用例有点不寻常,因为您需要消息组 ID 的功能,但不需要 FIFO。这有点像尝试对消息进行负载平衡。它通常通过拥有单独的队列来解决,例如高优先级队列和普通优先级队列,消费者首先处理高优先级队列。但是,想象一个场景,生产者 A 将 100 条消息放入队列,然后生产者 B 将 100 条消息放入队列,接下来应该拉取哪条消息?您正在寻求“平衡拉动”而不是 FIFO。这是一个不寻常的案例。

标签: amazon-sqs


【解决方案1】:

队列将按照您的描述运行,这是有意

只有两个不同的组 ID。如果两个组 ID 都在进行中,则无法检索其他消息。

如果这给您带来了问题,那么您很可能是错误地使用了组 ID。

组 ID 基本上是说“请按顺序处理这组消息”。因此,如果一条消息仍在处理中,SQS FIFO 队列会阻止来自同一组 ID 的另一条消息被检索和处理。您想要获取具有相同组 ID 的另一条消息这一事实向我表明,您确实希望按顺序处理该组消息,因此 您应该使用不同的组 ID

通过使用与生产者关联的组 ID,并且只有两个生产者,您将永远只有两个消费者处理队列。

【讨论】:

  • 我更新了问题,并解释了我尝试使用组 ID 和 FIFO 队列解决的问题。希望,解释清楚。
  • 您可以让每个生产者使用多个(例如两个)组 ID,这将允许消费者获取更多消息,但不能保证来自生产者 B 的消息获得优先级。您唯一的选择可能是两个有两个单独的队列,并让消费者优先从特定队列中拉取。
  • 更新了问题,其中描述了两种建议的解决方案。我认为,第二个可能有效。虽然,它增加了架构的复杂性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
相关资源
最近更新 更多