ChatGPT解决这个技术问题 Extra ChatGPT

为什么我应该使用 Amazon Kinesis 而不是 SNS-SQS?

我有一个用例,其中会有数据流,我不能以相同的速度使用它并且需要一个缓冲区。这可以使用 SNS-SQS 队列来解决。我知道 Kinesis 解决了相同的目的,那么有什么区别?为什么我应该更喜欢(或不应该更喜欢)Kinesis?


M
Marcel Gosselin

请记住,这个答案在 2015 年 6 月是正确的

在研究了这个问题一段时间后,考虑到同样的问题,我发现大多数用例都首选 SQS(带 SNS),除非消息的顺序对您很重要(SQS 不保证消息上的 FIFO)。

Kinesis 有两个主要优点:

您可以从多个应用程序中读取相同的消息,您可以在需要时重新读取消息。

通过使用 SNS 作为 SQS 的扇出可以实现这两个优势。这意味着消息的生产者只向 SNS 发送一条消息,然后 SNS 将消息扇出到多个 SQS,每个消费者应用程序一个。通过这种方式,您可以拥有任意数量的消费者,而无需考虑分片容量。

此外,我们还添加了一个订阅 SNS 的 SQS,该 SNS 将保留消息 14 天。在正常情况下,没有人从这个 SQS 中读取,但如果出现让我们想要回退数据的错误,我们可以轻松地从这个 SQS 读取所有消息并将它们重新发送到 SNS。而 Kinesis 仅提供 7 天的保留期。

总而言之,SNS+SQSs 更容易并且提供了大多数功能。 IMO 你需要一个非常强大的案例来选择 Kinesis。


仅供参考:您最多可以保留 Kinesis 7 天。
最近,AWS 发布了 SQS FIFO [docs.aws.amazon.com/AWSSimpleQueueService/latest/…,它可以服务于消息的时间排序。
超级次要评论 - 可能不会在 SNS split the message to multiple SQSs 中使用单词 split,因为它不会将消息分解成片段,而是将其复制到多个目的地。
Kinesis 不适用于扇出 (pub-sub) 用例,因为每个分片/秒的读取器数量受到限制。虽然与原始查询无关,但任何依赖 Kinesis 扩展到 n 阅读器的人都应该考虑到这一事实。 forums.aws.amazon.com/message.jspa?messageID=760351
Kinesis 的订单保证是每个分片,而不是每个流。一旦你有多个分片,整个流将无法保证顺序。对于一个 SQS 队列,当吞吐量比较低时,几乎是 FIFO。只有当您的吞吐量更高时,订单才会更少遵循。这是关于经典的 SQS 队列,而不是 FIFO 队列。
B
Bazzinga...

从表面上看,它们有点相似,但您的用例将决定哪种工具是合适的。 IMO,如果您可以使用 SQS,那么您应该 - 如果它可以满足您的需求,它将更简单、更便宜,但这里有一个来自 AWS 常见问题的更好解释,它提供了两种工具的适当用例示例帮助您决定:

FAQ's


仅供参考 docs.aws.amazon.com/AWSSimpleQueueService/latest/… SQS FIFO 不适用于 SNS
@Brent 只是为了保持最新 - AWS 在 SNS 中增加了对 FIFO SQS 的支持
R
Rohit Banga

Kinesis 支持多消费者能力,这意味着相同的数据记录可以在同一时间或 24 小时内的不同时间在不同的消费者处处理,SQS 中的类似行为可以通过写入多个队列来实现,消费者可以从多个队列中读取。然而,再次写入多个队列会在系统中增加亚秒 {几毫秒} 的延迟。

其次,Kinesis 提供路由功能,可以使用分区键选择性地将数据记录路由到不同的分片,该分区键可以由特定的 EC2 实例处理,并且可以启用微批量计算{计数和聚合}。

使用任何 AWS 软件都很容易,但使用 SQS 是最简单的。使用 Kinesis,需要提前配置足够的分片,动态增加分片数量以管理峰值负载并减少分片以节省管理成本。 Kinesis 很痛苦,SQS 不需要这样的事情。 SQS 是无限可扩展的。


关于你对 SQS 的解释。您可以通过在多个 SQS 之前放置一个 SNS 来实现将相同消息发送到多个 SQS 的简单方法。
app --> sns 主题 ---> sqs1, sqs2, sqs3... ?
是的,我指的是这种方法。
@RoeeGavirel sns api 的请求/秒限制怎么样?
@BarbarosAlp - 我只知道 SMS(移动短信)的限制,这不是这里的主题。这是官方文档:docs.aws.amazon.com/general/latest/gr/…
K
Konstantin Triger

这些技术的语义不同,因为它们旨在支持不同的场景:

SNS/SQS:流中的项目彼此不相关

Kinesis:流中的项目相互关联

让我们通过示例来了解差异。

假设我们有一个订单流,对于每个订单,我们需要保留一些库存并安排交货。完成后,我们可以安全地从流中删除该项目并开始处理下一个订单。在开始下一个订单之前,我们已经完成了上一个订单。同样,我们有相同的订单流,但现在我们的目标是按目的地对订单进行分组。一旦我们有 10 个订单到同一个地方,我们希望将它们一起交付(交付优化)。现在情况不同了:当我们从流中获得一个新项目时,我们无法完成对它的处理;相反,我们“等待”更多的项目来实现我们的目标。此外,如果处理器进程崩溃,我们必须“恢复”状态(因此不会丢失任何顺序)。

一旦一个项目的处理不能与另一个项目的处理分开,我们必须有 Kinesis 语义才能安全地处理所有情况。


使用 SQS FIFO 队列,我们将在发送消息时对其进行排序。这是否使 SQS 在这方面类似于 Kinesis?
@AndyDufresne:这很好地涵盖了顺序很重要的场景。在上述情况 (1) 中,您可能希望“按顺序”处理订单。因此,如果您缺货,以后的订单将被拒绝或延迟。 FIFO 语义不能解决核心相对性(分组)问题。
M
Matthew Curry

对我来说最大的优势是 Kinesis 是一个可重放队列,而 SQS 不是。因此,您可以拥有 Kinesis 的相同消息的多个消费者(或不同时间的同一消费者),其中使用 SQS,一旦消息被确认,它就会从该队列中消失。因此,SQS 更适合工作队列。


你如何确认消息?你的意思是删除吗?
是的,基本上。说您已完成此消息
这是不正确的,你在你的 sqsListener 上设置了删除策略,所以你可以说读时永远不要删除 msg
也许这是@farhad 的新事物,我在 7 年前回答了这个问题。有了这样的删除策略的侦听器会再次抓取相同的消息,还是允许您跳过消息?无论如何,SQS 的通常做法仍然更多是工作队列,尽管可以将其滥用于其他事情
P
Pang

摘自 AWS Documentation

对于具有类似于以下要求的用例,我们建议使用 Amazon Kinesis Streams: 将相关记录路由到相同的记录处理器(如在流式 MapReduce 中)。例如,当给定键的所有记录都路由到同一个记录处理器时,计数和聚合会更简单。记录排序。例如,您希望将日志数据从应用程序主机传输到处理/归档主机,同时保持日志语句的顺序。多个应用程序同时使用同一流的能力。例如,您有一个应用程序更新实时控制面板,而另一个应用程序将数据存档到 Amazon Redshift。您希望两个应用程序同时且独立地使用来自同一流的数据。能够在几个小时后以相同的顺序使用记录。例如,您有一个计费应用程序和一个在计费应用程序后几个小时运行的审计应用程序。由于 Amazon Kinesis Streams 最多可以存储 7 天的数据,因此您可以在计费应用程序之后最多 7 天运行审计应用程序。对于具有类似于以下要求的用例,我们建议使用 Amazon SQS:消息语义(例如消息级确认/失败)和可见性超时。例如,您有一个工作项目队列,并希望独立跟踪每个项目的成功完成情况。 Amazon SQS 跟踪确认/失败,因此应用程序不必维护持久的检查点/游标。 Amazon SQS 将在配置的可见性超时后删除确认的消息并重新传递失败的消息。个别消息延迟。例如,您有一个作业队列,需要延迟安排各个作业。使用 Amazon SQS,您可以将单个消息配置为最多延迟 15 分钟。在读取时动态增加并发/吞吐量。例如,您有一个工作队列并希望添加更多阅读器,直到清除积压。使用 Amazon Kinesis Streams,您可以扩展到足够数量的分片(但请注意,您需要提前预置足够的分片)。利用 Amazon SQS 的透明扩展能力。例如,由于偶尔的负载峰值或业务的自然增长,您可以缓冲请求和负载变化。由于每个缓冲的请求都可以独立处理,因此 Amazon SQS 可以透明地扩展以处理负载,而无需您提供任何预置指令。


这简洁地回答了这个问题
s
shonky linux user

另一件事:Kinesis 可以触发 Lambda,而 SQS 不能。因此,对于 SQS,您要么必须提供一个 EC2 实例来处理 SQS 消息(并在它失败时处理它),要么您必须有一个计划的 Lambda(它不会扩大或缩小 - 每分钟只有一个) .

编辑:这个答案不再正确。自 2018 年 6 月起,SQS 可以直接触发 Lambda

https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html


-1 不同意。虽然 Kinesis 可以触发 lambda,但与已调度的 SQS lambda 相比,这并没有优势。后者将无缝扩展(即,如果花费超过一分钟,第二个 lambda 将启动)。价格是按计算时间计算的,因此也没有明显的差异。如果您需要超过 5 个并发 lambda,那么只需添加多个间隔几秒钟安排的触发器(使用 cron)。这不是在 SNS/SQS 上使用 Kinesis 的理由。
我不确定我是否同意这种分歧;] - 您可以安排一个 lambda / 分钟,这将限制您批量处理到达该时间间隔的消息。 Kinesis 将允许您立即阅读消息。还是我误解了什么?
当需要针对 SQS 调用 pull lambda 时,几个 cloudwatch 触发器和数百个触发器之间存在巨大差异。
Lambda 现在支持 SQS 作为触发器!
J
John Velonis

定价模型不同,因此根据您的用例,一种或另一种可能更便宜。使用最简单的情况(不包括 SNS):

SQS 对每条消息收费(每 64 KB 计为一个请求)。

Kinesis 对每个分片每小时收费(1 个分片最多可以处理 1000 条消息或 1 MB/秒)以及您输入的数据量(每 25 KB)。

插入当前价格并且不考虑免费套餐,如果您以最大消息大小每天发送 1 GB 消息,Kinesis 将比 SQS 花费更多(Kinesis 每月 10.82 美元,SQS 每月 0.20 美元) .但是,如果您每天发送 1 TB,Kinesis 会便宜一些(每月 158 美元,而 SQS 每月 201 美元)。

详细信息:SQS 每百万个请求收费 0.40 美元(每个 64 KB),因此每 GB 0.00655 美元。按每天 1 GB 计算,每月只需不到 0.20 美元;每天 1 TB,每月 201 美元多一点。

Kinesis 每百万个请求收费 0.014 美元(每个 25 KB),因此每 GB 0.00059 美元。每天 1 GB,每月不到 0.02 美元;每天 1 TB,每月大约 18 美元。然而,Kinesis 也收取每分片小时 0.015 美元的费用。每秒每 1 MB 至少需要 1 个分片。在每天 1 GB 的情况下,1 个分片就足够了,因此每天将再增加 0.36 美元,每月的总成本为 10.82 美元。在每天 1 TB 的情况下,您将需要至少 13 个分片,这每天又增加了 4.68 美元,总成本为每月 158 美元。


我不完全理解为什么这里的大小呈指数增长很重要。你能再挖一点吗?听起来你有一些我想要的洞察力。编辑实际上,看看 Euguene Feingold 的回答,似乎对此(?)进行了相当激烈的辩论。
抱歉,我在计算中犯了一些错误(我希望现在已修复)。
是的,但是如果您的平均 SQS 消息大小很小,比如 1kb 或更小,该怎么办?
无论您的消息是 1 KB 还是 64 KB,@mcmillab SQS 都会收取相同的费用 - 请参阅 Amazon's SQS pricing page。因此,如果您的消息只有 1 KB,如果您发送相同的总数据量,SQS 的成本将是我上面给出的数字的 64 倍。但是,一个请求最多可以包含 10 条消息,因此如果您能够将消息批处理在一起,它可能只有 6 倍(取决于您的批处理的完整程度)。
@JohnVelonis 以上对 SQS 定价的计算缺少关键部分。需要特别注意了解 SQS 请求的收费方式。 1 个请求 = 1 个 API 操作。为了处理单个“消息”,至少需要执行 3 个 API 操作:1 个发送 + 1 个读取 + 1 个删除。其他 SQS 功能(例如更改可见性)将引发更多 API 操作。这种意想不到的乘数非常糟糕,通常会导致 SQS 比 Kinesis Streams 用于大型数据集(例如每月处理 1 亿条消息)的成本高 2-10 倍。
b
bhanu tadepalli

Kinesis 解决了流数据的典型 map-reduce 场景中的 map 部分问题。虽然 SQS 不能确定这一点。如果您有需要在密钥上聚合的流数据,kinesis 确保该密钥的所有数据都进入特定分片,并且该分片可以在单个主机上使用,与 SQS 相比,密钥上的聚合更容易


S
Sharhabeel Hamdan

Kinesis 用例

日志和事件数据收集

实时分析

移动数据采集

“物联网”数据馈送

SQS 用例

应用集成

解耦微服务

将任务分配给多个工作节点

将实时用户请求与密集的后台工作分离

用于将来处理的批处理消息


Kinesis 不能做您提到的 SQS 可以做的所有事情吗?
E
Eugene Feingold

我还要补充一件其他人没有提到的事情——SQS 的价格要贵几个数量级。


你确定吗?根据我的计算,Kinesis 要贵得多,但我从来没有使用过亚马逊简单价格计算器。
查看当前在 aws 上的定价示例:具有 2.67 亿条消息的 Kinesis 大约为 60 美元,而通过 SQS 发送该数量的消息将导致 107 美元。显然我只是做了一个非常快速的比较,这与不同的用例有很大的不同,但这个答案绝对应该得到一些赞誉。
假设你正在做一个扇形,说每天有 2 个消费者和 1 亿条消息。 SNS 费用为 50 美元/天。 SQS 成本为 40 美元/天/消费者或总计 80 美元/天。 Kinesis PUT 每天 1.4 美元,分片 0.36 美元。即使有 100 个分片(100 MB/s 输入,200 MB/s 输出),也只需 3.60 美元/天 + 1.40 美元/天。所以 Kinesis 每天 4 美元,而 SNS/SQS 每天 130 美元。
我很想知道为什么这个线程的成本存在如此差异。
SQS 定价的一个问题是,每 100 万个请求的规定成本率并不是实际消息。它是 API 操作,其中 1 个请求 = 1 个 API 操作。为了处理单个“消息”,至少需要执行 3 个 API 操作:1 个发送 + 1 个接收 + 1 个删除。其他 SQS 功能(例如更改可见性)将引发更多 API 操作。这种意想不到的乘数非常糟糕,通常会导致 SQS 比 Kinesis Streams 用于大型数据集(例如每月处理 1 亿条消息)的成本高 2-10 倍。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅