SQS 只传递一次消息
SQS delivering a message only once
假设我有 100 个线程从同一个 sqs 读取 -- 是否保证每条消息最多传递一次?是否有可能多次传递相同的消息?我找不到关于此问题的任何明确文档。小号
2016 年 11 月 17 日更新: FIFO queueing with guaranteed-once delivery 今天刚刚发布(在最初发布此答案后将近 2 年),SQS 现在支持恰好一次交付。详情如下:
- 您需要创建一个 FIFO Queue。
- 重复数据删除检查
MessageDeduplicationId
作为队列消息的属性,并通过检查 MessageDeduplicationId
来防止重复消息在任一操作后的 5 分钟重复数据删除间隔内发送和接收。
- 如果在 FIFO 队列上明确启用了基于内容的重复数据删除,
MessageDeduplicationId
将使用消息正文的 SHA-256 散列自动生成(仅内容,不是属性)。
- 如果未启用基于内容的重复数据删除,您必须在发送时为
MessageDeduplicationId
明确设置您自己的任意值。否则 SendMessage 将因错误而失败。
在 creating a queue or updating the queue' attributes 时可以启用基于内容的重复数据删除。
SendMessage and ReceiveMessage 文档中有关 MessageDeduplicationId 的更多详细信息。
2016 年 11 月 17 日之后,这仍然适用于标准(非 FIFO)队列:
由于 SQS 中标准(非 FIFO)队列的分布式特性,因此保证 "at least" 一次。
来自FAQ:
Q: How many times will I receive each message?
Amazon SQS is engineered to provide “at least once” delivery of all
messages in its queues. Although most of the time each message will be
delivered to your application exactly once, you should design your
system so that processing a message more than once does not create any
errors or inconsistencies.
有关 at least once 交付的更多信息:
Amazon SQS stores copies of your messages on multiple servers for redundancy and high availability. On rare occasions, one of the servers storing a copy of a message might be unavailable when you receive or delete the message. If that occurs, the copy of the message will not be deleted on that unavailable server, and you might get that message copy again when you receive messages. Because of this, you must design your application to be idempotent (i.e., it must not be adversely affected if it processes the same message more than once).
如果您确实需要在您的应用程序中保证 "at most once" 处理,您可能希望您的应用程序检查 unique identifiers of SQS messages 而不是处理您之前处理过或当前正在处理的消息 ID。
您需要使用 FIFO 队列,但您仍然需要生成一个数字来保证您的消息不会重复,您可以在将其发送到 SQS 之前在请求中使用您生成的数字设置 MessageDeduplicationId
。
更简单,您可以为 FIFO 队列打开 Content-Based-Deduplication
,让 AWS 自己为您管理重复,方法是根据已发送消息的内容创建哈希以避免重复数据删除。
- 从控制台,转到 SQS 服务,选择队列,然后从
Actions
选择 Configure queue
- 开启
Content-Based Deduplication
假设我有 100 个线程从同一个 sqs 读取 -- 是否保证每条消息最多传递一次?是否有可能多次传递相同的消息?我找不到关于此问题的任何明确文档。小号
2016 年 11 月 17 日更新: FIFO queueing with guaranteed-once delivery 今天刚刚发布(在最初发布此答案后将近 2 年),SQS 现在支持恰好一次交付。详情如下:
- 您需要创建一个 FIFO Queue。
- 重复数据删除检查
MessageDeduplicationId
作为队列消息的属性,并通过检查MessageDeduplicationId
来防止重复消息在任一操作后的 5 分钟重复数据删除间隔内发送和接收。 - 如果在 FIFO 队列上明确启用了基于内容的重复数据删除,
MessageDeduplicationId
将使用消息正文的 SHA-256 散列自动生成(仅内容,不是属性)。 - 如果未启用基于内容的重复数据删除,您必须在发送时为
MessageDeduplicationId
明确设置您自己的任意值。否则 SendMessage 将因错误而失败。
在 creating a queue or updating the queue' attributes 时可以启用基于内容的重复数据删除。
SendMessage and ReceiveMessage 文档中有关 MessageDeduplicationId 的更多详细信息。
2016 年 11 月 17 日之后,这仍然适用于标准(非 FIFO)队列:
由于 SQS 中标准(非 FIFO)队列的分布式特性,因此保证 "at least" 一次。
来自FAQ:
Q: How many times will I receive each message?
Amazon SQS is engineered to provide “at least once” delivery of all messages in its queues. Although most of the time each message will be delivered to your application exactly once, you should design your system so that processing a message more than once does not create any errors or inconsistencies.
有关 at least once 交付的更多信息:
Amazon SQS stores copies of your messages on multiple servers for redundancy and high availability. On rare occasions, one of the servers storing a copy of a message might be unavailable when you receive or delete the message. If that occurs, the copy of the message will not be deleted on that unavailable server, and you might get that message copy again when you receive messages. Because of this, you must design your application to be idempotent (i.e., it must not be adversely affected if it processes the same message more than once).
如果您确实需要在您的应用程序中保证 "at most once" 处理,您可能希望您的应用程序检查 unique identifiers of SQS messages 而不是处理您之前处理过或当前正在处理的消息 ID。
您需要使用 FIFO 队列,但您仍然需要生成一个数字来保证您的消息不会重复,您可以在将其发送到 SQS 之前在请求中使用您生成的数字设置 MessageDeduplicationId
。
更简单,您可以为 FIFO 队列打开 Content-Based-Deduplication
,让 AWS 自己为您管理重复,方法是根据已发送消息的内容创建哈希以避免重复数据删除。
- 从控制台,转到 SQS 服务,选择队列,然后从
Actions
选择Configure queue
- 开启
Content-Based Deduplication