SQS 与 RabbitMQ

SQS vs RabbitMQ

我需要创建一个队列进行处理。队列本身的容量相对较小。每小时可能有大约 1,000 次写入。每个任务的执行可能需要大约一分钟,并且几乎在将项目添加到队列后立即处理。

我是否有任何理由想要实施 RabbitMQ 而不是像 Amazon SQS 这样现成的东西?应用程序需要自己的排队系统而不是 SQS 之类的系统的原因有哪些?

首先,Amazon SQS 是一个伪队列,这意味着每条消息(如果它到达队列)的传递都得到保证,但不是以队列中通常发生的 FIFO 方式传递。

如果消息的顺序对您很重要并且您希望队列以 FIFO 方式工作,Amazon SQS 文档说明在您的应用程序逻辑中处理此问题,因为来自 Amazon SQS 的消息将到达您顺序。

与此相比,据我所知,您可以在RabbitMQ中实现工作队列。如果这使您无需在应用程序级别实施队列消息排序,那么这将是一个更可取的选择。

以下几个因素可以帮助您决定选择哪一个:

  1. 队列消息序列如上。

  2. 您可以使用 RabbitMQ 设置您自己的服务器,但在 Amazon SQS 的情况下则不行,因此此处涉及成本。

  3. 设置您自己的服务器需要对该主题有很好的了解,这样您就不会遗漏任何角落。 Amazon SQS 不是这种情况,因为它上手非常快。

  4. 您自己的 RabbitMQ 服务器意味着维护成本下降,而 Amazon SQS 则不然。

更新:

  1. Amazon SQS 现在支持 FIFO 队列。

相比 RabbitMQ,我更喜欢 SQS,原因如下。

  1. SQS 是一项托管服务。因此,您不必担心 运行 消息传递系统的操作方面,包括管理、安全、监控等。亚马逊会为您完成这些工作,并会在出现问题时提供支持。
  2. SQS 是弹性的,可以扩展到非常大 rate/volumes(根据 AWS 没有限制;))
  3. SQS 的可用性有很多 9,并且由 Amazon 提供支持,这让您的应用程序无需担心。

但是,根据我的测试,RabbitMQ 可能会为放置和获取提供更快的响应时间,通常在数千 TPS 的几十秒内。要使 SQS 提供这种吞吐量,您将必须使用多个实例水平扩展。因此,如果您正在寻找 5 毫秒以下的放置时间,RabbitMQ 可能是一个可以考虑的选项,因为我在 1000s TPS 下的 SQS 测试中看到接近 20ms-30ms 的放置时间,这比 RabbitMQ 略高。

我们刚刚将我们的消息传递基础架构从 ActiveMQ 迁移到 SQS,再高兴不过了。我们发现它比在云中维护我们自己的 ActiveMQ 集群更便宜。

希望对您有所帮助!让我们知道进展如何..

我实际上在商业环境中使用了两者并取得了合理的成功。

简短的回答是,除非有特定的极端情况,否则最好使用 AWS SQS。 (简单总结可以跳到底部)

编码(并列): RabbitMQ 和 AWS SQS 都建立了库和大量的例子。

可见性超时 (SQS): SQS 提供超过 RabbitMQ 的一件事是更广泛的可见性超时概念。在 RabbitMQ 中,如果消费者在它确认之前死亡,消息将被放回队列中。但是 SQS 有一个更广泛的可见性超时概念,它不依赖于特定的调用者。因此,您可以启动一个工作单元,设置可见性并设置较长的超时时间(最多 12 小时),断开连接,让另一个工作人员完成并确认它。在我的设计中,我们广泛利用了这一点并消除了额外的 service/storage 来管理潜在的大 'in progress' 有效负载。

死信处理(RabbitMQ - 'hare') SQS 在所谓的“重新驱动策略”中提供基本的死信处理,将消息转储到死信队列(只是另一个队列)中。它是基本的,只有消息计数的概念。 RabbitMQ 有 Dead Letter Exchanges,它提供消息在过期时被推送到 DLE。但这有点没有实际意义,因为“如果您没有看到您的服务和消息过期,那么它将进入 DLE”。这对 RabbitMQ 来说是一个小小的胜利,因为我发现这个论点有悖于直觉。你为什么要监控你的队列而不是你的服务? (如果有的话,它是相反的)

管理(SQS): 没有对 SQS 的管理。您只需为 API 次通话付费。 OS/app 安全补丁、扩展(添加更多节点)、磁盘等所有常见问题均由 AWS 团队处理。它还符合 FedRamp 标准(供政府使用)。这是一个真正的 'setup and forget' 系统。 RabbitMQ 需要通常的 OS/service 补丁、AMI、集群、安全强化等。虽然这种情况极为罕见,但 AMI 可能会出现故障,或者有时需要四处移动,因此需要开箱即用的集群。 SQS 消除了所有这些麻烦。

成本(SQS): 单个 SQS API 调用可以包含 'batch up to 10 messages/256k size' 并且 'long polling' 可以大大降低成本。此外,还有诸如消息压缩之类的策略,可以将数十条(有些声称数百条或更多条)消息发送到单个有效负载中,从而进一步降低成本。这是在我们考虑人们花费 monitoring/patching/fixing 的时间问题之前。 SQS 也非常适合 'poc projects',就好像它闲置一样,没有任何成本。

先进先出(并列): 2016 年,AWS 引入了 FIFO 支持,每百万 api 次调用的额外成本为 0.10 美元(FIFO 队列为 0.50 美元,而标准(非 FIFO)队列每百万 API 请求为 0.40 美元,均在折扣前)。您可以选择是否使用 FIFO。对于非 FIFO,我们很少看到重复消息。

存储(SQS): AWS 不对存储收费,但您有 14 天的限制。在 RabbitMQ 上,您必须分配、扩展和管理需要峰值存储容量和额外缓冲区的磁盘 space。就是比较头疼

指标(SQS): SQS 提供开箱即用的指标。虽然您可以将它们添加到 AWS,但工作量更大。

本地开发人员(并列): 大多数现代商店都喜欢拥有当地环境。现在有几个选项允许 RabbitMQ 和 SQS 的 docker。

高 throughput/very 大消息(RabbitMQ - 有点) 当您推动 SQS > 1000 requests/sec 时,SQS 的延迟会增加。有几种策略可以绕过它。但我发现这些情况极为罕见,因为大多数工作都可以划分到多个队列中。但是对于这些需要 100k/sec 的情况,我认为 Kafka 更好。 (我们在工作中也使用 Kafka)很少有单个工作单元需要 1000+ request/second 且延迟很低。 *有关此解释,请参阅下面的更多内容

总结: 如果你打算在 AWS 工作并愿意与 SQS 联姻,那么 SQS 是不二之选。但是您应该继续阅读,因为有一些重要的事情需要考虑。

RabbitMQ(和其他队列)的经典策略是创建针对某些类型的工作优化的多种类型的队列。然后微调这些队列中的每一个并将类似的工作分组到少数这些(通常非常大)队列中。由于 SQS 没有管理开销,为每个工作分配专用队列实际上更好。通过这样做,它允许扩展,但也消除了队列饱和(有问题的工作使队列饱和并淹没其他工作人员),更好地查看工作(默认指标)等。

新策略让我的团队能够更好地了解工作分配方式。 'upgrading instance for more load' 的日子已经一去不复返了。过去,我们会看到一个无法解释的大峰值,这会对其他服务造成副作用,或者只是猜测累积数字 看起来很对'。现在流量分开了,我们其实发现了很多以前没有注意到的问题,可以很清楚的说明多少流量去哪里了。虽然很可能实施指标和工具,但 SQS 提供了所有这些开箱即用的功能。

RabbitMQ 仍然有很多值得认真考虑的案例

- Very large legacy code base that uses RabbitMQ with extensive tooling and knowledgeable support staff
- Messages that needs to be in the same work stream for > 14 days
- Very large messages that has very low latency requirements with it
- Cloud agnostic code base requirements. If you must run your code on other platforms (e.g. Azure/Google/bare metal), then SQS is not an option
- Large volume of data for a single pipeline that can't be broke up and other solutions (e.g. Kafka) are not viable. But at a super large volume, Kafka is a lot faster. While SQS will push large payloads to S3, you are now incurring additional cost.

如果您对成本很敏感,Amazon SQS 可能会更贵。我说可能是因为您仍然需要在某个地方托管您的 RabbitMQ 服务器。 SQS 为您提供前 100 万个免费请求,之后每百万个请求收取 0.4 美元。有一个技巧可以通过启用长轮询来降低 SQS 的成本,即将 receive_message_wait_time 设置为 20s。这并不意味着您的消息只会每 20 秒发送一次,而是意味着如果您的查询为空(每 20 秒),SQS 不会向您收取 'request' 费用。

如果您每小时使用 1000 个请求,那么您一个月的处理量是 744000 个。免费层内免费,层外约 0.74*0.4 美元 = 0.2976 美元。您可以通过启用等待时间来进一步减少。因此,在您的情况下,SQS 实际上可能更便宜,因为大多数托管起价至少为 5 美元以上(除非您拥有 AWS 提供的 EC2 免费套餐)。您应该可以选择最小的选项,因为 RMQ 只推荐 128mb 左右的 ram。

如果您愿意的话,我发现 SQS 更加用户友好,而 RabbitMQ 更加技术化。

更新:

实际上我发现 AWS Simple Notification Service 更适合我的需要主要是因为它基于推送,即不轮询