我有一个使用情况,其中会有一系列的数据流进来,而我无法以相同的速度消耗它们,因此需要一个缓冲区。这可以使用SNS-SQS队列来解决。我了解到Kinesis也可以解决同样的问题,那么它们之间有什么区别?为什么应该选择(或不选择)Kinesis?
我有一个使用情况,其中会有一系列的数据流进来,而我无法以相同的速度消耗它们,因此需要一个缓冲区。这可以使用SNS-SQS队列来解决。我了解到Kinesis也可以解决同样的问题,那么它们之间有什么区别?为什么应该选择(或不选择)Kinesis?
请记住,此答案适用于2015年6月之前的情况
经过一段时间的研究后,我发现在大多数情况下,SQS(配合SNS)是首选,除非您对消息的顺序很重要(SQS无法保证消息的FIFO)。
Kinesis有两个主要优点:
通过将SNS作为扇出到SQS来实现这两个优点。这意味着消息的生产者只向SNS发送一条消息,然后SNS将消息扇出到多个SQS,每个消费者应用程序一个SQS。这样,您可以拥有任意数量的消费者,而不必考虑分片容量。
此外,我们还添加了另一个SQS,它订阅了可保存14天的SNS消息。在正常情况下,没有人从此SQS中读取,但是如果存在使我们想要倒带数据的bug,则可以轻松地从此SQS中读取所有消息并将其重新发送到SNS。而Kinesis仅提供7天的保留期。
总之,SNS+SQS更容易且提供了大多数功能。在我看来,除非有非常强的理由选择Kinesis,否则应该选择SNS+SQS。
这些技术的语义不同,因为它们被设计用于支持不同的场景:
让我们通过例子来了解它们的区别。
一旦一个项目的处理无法与处理另一个项目分离,我们就必须具备Kinesis语义以安全地处理所有情况。
表面上它们有些相似,但你的使用情况将决定哪个工具更适合。依我看,如果你能够使用 SQS 完成想要的功能,那么就应该使用它,因为它更简单、更便宜。但是在 AWS 的常见问题解答中提供了更好的解释,其中给出了两种工具的适用场景示例,以帮助你做出决策:
Kinesis支持多个消费者的功能,这意味着相同的数据记录可以在24小时内同时或不同时处理在不同的消费者中,类似的行为在SQS中可以通过写入多个队列并且消费者可以从多个队列读取来实现。但是,再次写入多个队列会在系统中添加子秒{几毫秒}延迟。
其次,Kinesis提供路由功能,使用分区键将数据记录有选择地路由到不同的分片中,可以由特定的EC2实例处理并启用微批量计算{计数和聚合}。
在任何AWS软件上工作都很容易,但是在SQS上最容易。对于Kinesis,需要提前分配足够数量的分片,动态增加分片数量以管理峰值负载并减少成本也是必需的。这在Kinesis中很痛苦,在SQS中不需要这样的东西。SQS是无限可扩展的。
以下内容摘自AWS文档:
我们建议使用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可以透明地扩展以处理负载,而无需您提供任何预配指令。
对我来说,最大的优势是 Kinesis 是可重放队列而 SQS 不是。因此,您可以在 Kinesis 上拥有相同消息的多个消费者(或不同时段的同一消费者),而对于 SQS,则一旦确认了消息,它就会从队列中消失。因此,SQS 对于工作队列来说更好。
另外,Kinesis可以触发Lambda,而SQS则不行。因此,使用SQS时,你要么必须提供一个EC2实例来处理SQS消息(并处理它失败的情况),要么必须有一个定时Lambda(无法扩展或缩小 - 每分钟只有一个)。
编辑:这个答案已经不正确了。自2018年6月起,SQS可以直接触发Lambda。
计费模型不同,因此根据您的使用情况,其中一个可能更加便宜。 在最简单的情况下(不包括 SNS):
根据当前价格,不考虑免费套餐,如果您以最大消息大小每天发送 1 GB 的消息,则 Kinesis 的成本将比 SQS 高得多(Kinesis 为 $10.82/月,而 SQS 为 $0.20/月)。 但是,如果您每天发送 1 TB,则 Kinesis 稍微便宜一些($158/月 vs. $201/月 的 SQS)。
详情: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/shard-hour 收费。您每秒至少需要 1 个 shard 来处理 1 MB 的数据。每天 1 GB,1 个 shard 完全足够,因此这将增加每天 $0.36 的费用,总成本为 $10.82/月。每天 1 TB,您至少需要 13 个 shards,这又增加了每天 $4.68 的费用,总共需花费 $158/月。
Kinesis解决了流式数据的typical map-reduce情景中地图部分问题。而SQS并没有保证这一点。如果您有需要根据键聚合的流式数据,Kinesis会确保该键的所有数据都进入特定的shard,并且可以在单个主机上消耗该shard,相比之下使用SQS更容易进行键聚合。
Kinesis使用案例
SQS使用案例