What is a good practice to achieve the "Exactly-once delivery" behavior with Amazon SQS?
Asked Answered
D

4

25

According to the documentation:

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.

Is there any good practice to achieve the exactly-once delivery?

I was thinking about using the DynamoDB “Conditional Writes” as distributed locking mechanism but... any better idea?


Some reference to this topic:

Dodwell answered 21/11, 2012 at 1:4 Comment(2)
BTW in the end I used “DynamoDB Conditional Writes”Dodwell
The following article sums up the solutions (Idempotent vs using locks) pretty well linkedin.com/pulse/…Clevey
Q
10

FIFO queues are now available and provide ordered, exactly once out of the box.

https://aws.amazon.com/sqs/faqs/#fifo-queues

Check your region for availability.

Quern answered 16/12, 2016 at 2:20 Comment(2)
FIFO queues are not compatible with SNS , so if you are using a combination of SNS+SQS you can't use it. docs.aws.amazon.com/AWSSimpleQueueService/latest/…Stammel
AWS FIFO queues provied exactly once ONLY IF all the parties (producer, queue and consumer) are single threaded and more.. I would suggest reading this article for more info - linkedin.com/pulse/truth-aws-sqs-fifo-harleen-mannBrewis
B
9

The best solution really depends on exactly how critical it is that you not perform the action suggested in the message more than once. For some actions such as deleting a file or resizing an image it doesn't really matter if it happens twice, so it is fine to do nothing. When it is more critical to not do the work a second time I use an identifier for each message (generated by the sender) and the receiver tracks dups by marking the ids as seen in memchachd. Fine for many things, but probably not if life or money depends on it, especially if there a multiple consumers.

Conditional writes sound like a clever solution, but it has me wondering if perhaps AWS isn't such a great solution for your problem if you need a bullet proof exactly-once solution.

Biometry answered 21/11, 2012 at 9:25 Comment(1)
+1 I agree, Amazons trade offs for sqs downgrades it as a messaging solution for many types of applications. I wish they would offer their own sync solution as an optional behavior you could enable at an understood performance cost, instead of all of us having to labor over the same workarounds.Saber
C
4

Another alternative for distributed locking is Redis cluster, which can also be provisioned with AWS ElasticCache. Redis supports transactions which guarantee that concurrent calls will get executed in sequence.

One of the advantages of using cache is that you can set expiration timeouts, so if your message processing fails the lock will get timed release.

Cynthla answered 15/8, 2014 at 0:2 Comment(0)
O
1

In this blog post the usage of a low-latency control database like Amazon DynamoDB is also recommended: https://aws.amazon.com/blogs/compute/new-for-aws-lambda-sqs-fifo-as-an-event-source/

Amazon SQS FIFO queues ensure that the order of processing follows the message order within a message group. However, it does not guarantee only once delivery when used as a Lambda trigger. If only once delivery is important in your serverless application, it’s recommended to make your function idempotent. You could achieve this by tracking a unique attribute of the message using a scalable, low-latency control database like Amazon DynamoDB.

In short - we can put item or update item in dynamodb table with condition expretion attribute_not_exists(for put) or if_not_exists(for update), please check example here https://mcmap.net/q/419914/-how-to-insert-to-dynamodb-just-if-the-key-does-not-exist

If we get an exception during put/update operations, we have to return from a lambda without further processing, if not get it then process the message (https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/)

The following resources were helpful for me too:

https://ably.com/blog/sqs-fifo-queues-message-ordering-and-exactly-once-processing-guaranteed

https://aws.amazon.com/blogs/aws/introducing-amazon-sns-fifo-first-in-first-out-pub-sub-messaging/

https://youtu.be/8zysQqxgj0I

Opec answered 24/9, 2021 at 18:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.