【问题标题】:Amazon SNS 和 Amazon SQS 有什么区别?
【发布时间】:2012-11-20 19:09:54
【问题描述】:

我什么时候会使用 SNS 和 SQS,为什么它们总是耦合在一起?

【问题讨论】:

标签: amazon-web-services amazon-sqs amazon-sns


【解决方案1】:

耦合 SQS 和 SNS 的一个原因是数据处理管道。

假设您正在生成三种产品,并且产品 B 和 C 都源自同一个中间产品 A。对于您设置的每种产品(即,对于管道的每个部分):

  • 用于生成产品的计算资源(可能是 lambda 函数、虚拟机集群或自动扩缩的 kubernetes 作业)。
  • 一个队列(描述需要执行的工作单元),用于跨计算资源划分工作(以便每个工作单元只处理一次,但单独的工作单元可以单独并行和异步处理)彼此)。
  • 新闻提要(宣布已生成的输出)。

然后安排 B 和 C 的输入队列都订阅 A 的输出公告。

这使得管道在基础设施级别上模块化。与其拥有一个同时生成所有三个产品的单一服务器应用程序,流水线的不同阶段可以利用不同的硬件资源(例如,阶段 B 可能非常占用内存,但其他两个阶段可以使用更便宜的硬件/服务来执行) .这也使得在不中断其他产品交付的情况下迭代开发一个管道段变得更加容易。

【讨论】:

    【解决方案2】:

    以下是 AWS 上主要消息传递技术(SQS、SNS、+EventBridge)之间的主要区别。为了选择一个特定的 AWS 服务,我们应该知道一个服务提供的功能以及它与其他服务的比较。

    下图总结了该服务之间的主要异同。

    【讨论】:

      【解决方案3】:

      简单来说,

      • SNS - 使用推送机制向订阅者发送消息,无需拉取。

      • SQS - 它是分布式应用程序使用的消息队列服务,通过轮询模型交换消息,可用于解耦发送和接收组件。

      一种常见的模式是使用 SNS 将消息发布到 Amazon SQS 队列,从而可靠地将消息异步发送到一个或多个系统组件。

      来自Amazon SNS FAQs的参考。

      【讨论】:

      • SQS 无法将消息发送到 许多系统,因为它不会散出消息。是的,许多轮询器可以从中提取消息,但是如果一个消费者删除了该消息,那么其他订阅者将无法再次使用相同的消息。如果要实现扇出模式,则 SNS 优于 SQS。此外,如果设置了visibilityTimeout,则一旦消息被其他系统处理,其他系统将无法使用该消息。
      • 一种常见的模式是使用 SNS 将消息发布到 Amazon SQS 队列,从而可靠地将消息异步发送到一个或多个系统组件。参考来自aws.amazon.com/sns/faqs
      • 如果这就是您的意思(SNS -> 多个 SQS 队列),那么请编辑您的答案,我会很乐意删除我的反对票。照你说的方式,听起来 SQS 可以扇出。
      • 是的..这就是混乱所在。我已经编辑了它..谢谢:)
      • 这是一个开始,但问题是关于差异等:“我什么时候使用 SNS 与 SQS,为什么它们总是耦合在一起?” 也许更直接地解决这个问题?您可以edit your answer没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的)。
      【解决方案4】:

      您可以将 SNS 视为一个可以有多个订阅者的传统主题。例如,对于一个给定的 SNS 主题,您可以拥有异构订阅者,包括 LambdaSQS。您还可以使用 SNS 开箱即用地发送 SMS 消息甚至电子邮件。在 SNS 中要考虑的一件事是一次只收到一条消息(通知),因此您无法利用批处理。

      另一方面,

      SQS 只不过是一个队列,您可以在其中存储消息并订阅一个消费者(是的,您可以让 N 个消费者加入一个 SQS 队列,但是考虑到所有消费者都需要至少阅读一次消息,它会很快变得混乱并且更难管理,因此对于这个用例,SNS 结合 SQS 会更好,其中 SNS 会将通知推送到 N 个 SQS 队列每个队列只有一个订阅者)来处理这些消息。自 2018 年 6 月 28 日起,AWS Supports Lambda Triggers for SQS,这意味着您不再需要投票来获取消息。

      此外,您可以在源 SQS 队列上配置 DLQ,以便在发生故障时向其发送消息。如果成功,消息会被自动删除(这是另一个很大的改进),因此您不必担心已经处理的消息被再次阅读,以防您忘记手动删除它们。我建议查看Lambda Retry Behaviour 以更好地了解它的工作原理。

      使用 SQS 的一大好处是它支持批处理。每个批次最多可以包含 10 条消息,因此如果 100 条消息同时到达您的 SQS 队列,那么 10 个 Lambda 函数将启动(考虑到 Lambda 的默认自动扩展行为),它们将处理这 100 条消息(保留在请注意,这是实践中的快乐路径,更多的 Lambda 函数可能会启动读取少于批处理中的 10 条消息,但你明白了)。但是,如果您将这 100 条相同的消息发布到 SNS,则会启动 100 个 Lambda 函数,从而不必要地增加成本并耗尽您的 Lambda 并发。

      但是,如果您仍在运行传统服务器(例如 EC2 实例),您仍然需要轮询消息并手动管理它们。

      您还有 FIFO SQS 队列,它保证了消息的传递顺序。 SQS FIFO is also supported as an event source for Lambda 截至 2019 年 11 月

      尽管它们的用例有一些重叠,但 SQS 和 SNS 都有自己的亮点。

      在以下情况下使用 SNS

      • 需要多个订阅者
      • 开箱即用发送短信/电子邮件很方便

      在以下情况下使用 SQS

      • 只需要一个订阅者
      • 批处理很重要

      【讨论】:

      • 许多 消费者之间分配任务是 SQS 的主要预期用例。 (无论消费者一次检索 1 条消息还是 10 条消息,由应用程序来控制同时存在的消费者数量。)它与 SNS 不同,因为 SNS 尝试将每条消息发送给所有订阅者,而 SQS 尝试将消息分区消费者之间的消息。
      【解决方案5】:

      这是两者的比较:

      实体类型

      • SQS:队列(类似于 JMS)
      • SNS:主题(Pub/Sub 系统)

      消息消费

      • SQS:拉取机制 - 消费者从 SQS 轮询和拉取消息
      • SNS:推送机制 - SNS 将消息推送给消费者

      用例

      • SQS:解耦两个应用程序并允许并行异步处理
      • SNS:扇出 - 以多种方式处理同一消息

      持久性

      • SQS:如果没有可用的消费者(最多两周),消息会保留一段时间(可配置),因此在将消息添加到队列时消费者不必启动。
      • SNS:没有持久性。消息到达时在场的任何消费者都会收到消息并删除消息。如果没有可用的消费者,则在重试几次后消息会丢失。

      消费者类型

      • SQS:所有消费者通常都是相同的,因此以完全相同的方式处理消息(每条消息由一个消费者处理一次,但在极少数情况下可能会重新发送消息)
      • SNS:消费者可能以不同的方式处理消息

      示例应用程序

      • SQS:作业框架:作业提交给 SQS,另一端的消费者可以异步处理作业。如果作业频率增加,则可以简单地增加消费者数量以实现更好的吞吐量。
      • SNS:图像处理。如果有人将图像上传到 S3,然后为该图像添加水印、创建缩略图并发送一封 谢谢 电子邮件。在这种情况下,S3 可以将通知发布到一个 SNS 主题,三个消费者正在监听它。第一个为图像添加水印,第二个创建缩略图,第三个发送 Thank You 电子邮件。它们都收到相同的消息(图片 URL)并并行处理。

      【讨论】:

      • 如果没有可用的消费者,则有重试机制,甚至默认值为10次重试。
      • 好详细的帖子。我们对不同的消费者有不同的消息 - 我们应该怎么做 - 使用 SNS 并定义不同的主题或使用 SQS 并定义不同的队列?一个主题/队列可能有一个或多个消费者。
      • 我不认为“SQS:所有消费者都应该是相同的,因此以完全相同的方式处理消息”这是正确的。我使用了 SQS,其中两种不同的 AWS 服务从 SQS 队列中提取并以自己的方式处理消息(这些不同服务中的不同应用程序逻辑)。我错过了什么吗?
      • @nad 我需要了解您的用例,但对我来说,两个 SQS 消费者以不同的方式处理消息是没有意义的。这是 SNS 的一个用例
      • 是的,但是谁删除了该消息。消费者 1 和消费者 2 和消费者 3 会不会一次又一次地收到相同的消息
      【解决方案6】:

      AWS SNS 是一个发布者订阅者网络,订阅者可以订阅主题,并且只要发布者发布到该主题,订阅者就会收到消息。

      AWS SQS 是一种队列服务,它将消息存储在队列中。 SQS 无法传递任何消息,需要外部服务(lambda、EC2 等)来轮询 SQS 并从 SQS 中获取消息。

      SNS 和 SQS 可以出于多种原因一起使用。

      1. 可能有不同类型的订阅者,其中一些需要 即时传递消息,其中一些需要消息 持久化,以供以后通过轮询使用。见this link

      2. 扇出模式。”这是为了异步处理 消息。当消息发布到 SNS 时,它可以分发它 并行到多个 SQS 队列。加载时这可能很棒 应用程序中的缩略图并行,当图像被 发表。见this link

      3. 永久存储。当要处理消息的服务不可靠时。在这种情况下,如果 SNS 推送一个 通知服务,并且该服务不可用,则 通知将丢失。因此我们可以使用 SQS 作为持久化 存储,然后再进行处理。

      【讨论】:

      • 只有您的评论清楚地解释了如何将 SNS 和 SQS 结合起来。谢谢!
      • 我是 AWS 的新手,但 3. 自从写完答案后发生了变化? [docs.aws.amazon.com/sns/latest/dg/… Delivery Retries) Amazon SNS 为每个交付协议定义了一个交付策略。传送策略定义了 Amazon SNS 在发生服务器端错误时(当托管订阅终端节点的系统不可用时)如何重试消息传送。当传输策略用尽时,Amazon SNS 将停止重试传输并丢弃消息 — 除非订阅附加死信队列。
      • @buzztr 3. 没有改变;它指的是 SQS 的使用者变得不可用。您引用的该文档描述了 SNS 的一个新功能,其中在用尽重试后未能将消息传递给消费者(在本例中为 SQS)导致 SNS 将该消息放入专用的 SQS 队列以进行处理传输错误。这意味着您不会完全丢失消息,而是将其保存并在以后重新尝试通过 SNS 主题进行传输。
      【解决方案7】:

      来自 AWS 文档:

      Amazon SNS 允许应用程序将时间关键型消息发送到 多个订阅者通过“推送”机制,无需 定期检查或“轮询”更新。

      Amazon SQS 是分布式应用程序使用的消息队列服务 通过轮询模型交换消息,并可用于 解耦发送和接收组件——不需要每个 组件同时可用。

      Fanout to Amazon SQS queues

      【讨论】:

      • SQS 可以“轮询等待消息进来”(类似于推送)。但它只处理该消息一次,所以它不是广播推送,FWIW :)
      【解决方案8】:

      SNS 是一个分布式发布-订阅 系统。消息在发布者发送到 SNS 时推送给订阅者。

      SQS是分布式排队系统。消息推送给接收者。接收者必须从 SQS轮询或提取消息。多个接收者不能同时接收消息。任何一个接收者都可以接收、处理和删除消息。其他接收者稍后不会收到相同的消息。与 SNS 不同,轮询在 SQS 中的消息传递中固有地引入了一些延迟,后者将消息立即推送给订阅者。 SNS 支持多个端点,例如电子邮件、SMS、HTTP 端点和 SQS。如果您希望未知数量和类型的订阅者接收消息,则需要 SNS。

      您不必总是将 SNS 和 SQS 结合起来。除了 SQS,您还可以让 SNS 向电子邮件、SMS 或 HTTP 端点发送消息。将 SNS 与 SQS 耦合具有优势。您可能不希望外部服务与您的主机建立连接(防火墙可能会阻止从外部到您的主机的所有传入连接)。

      您的端点可能会因为大量消息而死掉。电子邮件和 SMS 可能不是您快速处理消息的选择。通过将 SNS 与 SQS 耦合,您可以按照自己的节奏接收消息。它允许客户端离线,容忍网络和主机故障。您还可以实现有保证的交付。如果您将 SNS 配置为向 HTTP 端点或电子邮件或 SMS 发送消息,则多次发送消息失败可能会导致消息被丢弃。

      SQS主要用于解耦应用程序或集成应用程序。消息可以在 SQS 中存储很短的时间(最长 14 天)。 SNS 将多个消息副本分发给多个订阅者。例如,假设您要将应用程序生成的数据复制到多个存储系统。您可以使用 SNS 并将这些数据发送给多个订阅者,每个订阅者都将收到的消息复制到不同的存储系统(S3、主机上的硬盘、数据库等)。

      【讨论】:

      • 所以基本上,要实现推送通知消息之类的东西,建议使用 SNS 和 SQS,这样带有 sns 的推送将排队,直到用户只是从队列中检索它们?是否可以为每个用户创建一个队列?
      • 是的。您可以拥有任意数量的 SNS 订阅者。您可以将通知发送到多个队列。
      • @NickGinanto 每个用户的队列可能不是您想要的。您可能希望每个服务都有一个队列,然后处理特定于用户的消息。此图可能会有所帮助:aws.amazon.com/blogs/aws/…
      • 应该注意的是,截至 2018 年年中,SQS 可以触发 lambda,因此在这种情况下更类似于 pubsub。
      • 这是迄今为止我遇到的关于这两种 AWS 服务的最好、最简单的解释。