AWS Bites Podcast

22. What do you need to know about SQS?

Luciano and Eoin take a deep dive into SQS as part of a series on AWS event services and event-driven architecture. We talk about the kind of problems SQS can solve, all of the SQS features and how to configure and use SQS to achieve reliability and scalability without all the complexity. We also take some time to detail how SQS works with Lambda in terms of scaling, batching and filtering.

In this episode we mentioned the following resources:

Let's talk!

Do you agree with our opinions? Do you have interesting AWS questions you'd like us to chat about? Leave a comment on YouTube or connect with us on:

Luciano
00:01:02

We mentioned that decoupling producers and consumers is generally a good use case for SQS. Also, it's a good service to add reliability because basically when you add SQS, you have an easy way to store messages persistently, so you can consume them later and this is good for instance in cases where your consumer might not be immediately available or it might be overloaded. You can have a queue in between and that allows you to be able to manage these kind of situations in a more reliable way. The other thing is that a characteristic of SQS is that each message is expected to be processed by one consumer and that will have implications that we'll discuss later with some of the examples. Also, multiple consumers allows you to scale highly. For instance, if you are producing many, many messages and for some reason your application is not working, you can for some reason your application is more and more successful, so the number of messages grows exponentially, you can keep allocating more and more consumers and you will just get all the messages being distributed and you can compute in a more parallelized way. So that let's say SQS is generally a good way to scale workloads when the number of items to process increases over time. And the other thing is that it can be used even for cross-region or cross-account communication because from one region you can publish messages in another region or even from one account you can publish messages in another account. So it can be used for communicating that way across regions and accounts. Is there any example use case that you want to mention to try to clarify these points we just mentioned?

Eoin
00:02:56

There are loads of use cases where you can really make great use of SQS but I suppose some of the simple ones we talked about the last time were you want to send an email so you could have a service that consumes email sending requests and SQS is ideal for that or if you have some sort of batch processing like a service to process picture resizing requests. That's a typical example and you can imagine the same thing being applied to a lot of enterprise batch processing workloads as well like if you're doing some sort of calculation or modeling an aggregation task these are all jobs that you can put on an SQS queue and then have one or many many workers that pull from that queue. It could be an AI modeling workload as well so you can just imagine having a pool of workers and that pool can scale auto scale according to the queue depth the number of messages in your queue. That's a pretty typical pattern. You've also got I suppose thinking like about enterprise architecture or event driven microservices the architecture and decoupling systems SQS is really useful in all of those situations so decoupling within systems at a finer grain or at a macro level across a big enterprise full of applications. So yeah that's that's particularly useful you could also use it as an SNS subscription so we mentioned that it's a point-to-point channel but you can also use it with PubSub and together you get point-to-point with reliability or sorry PubSub with reliability. You also have DLQs so DLQs there's lots of enterprise integration patterns and DLQ is one of the most well known and that's essentially a dead letter queue which so it's a queue where if you have messages that have failed to be processed repeatedly you can put them into a dead letter queue and then manually re-inspect them and schedule them for redelivery later. So SQS queues can be used as DLQs in their own right with any system but SQS also has a feature but SQS also has a feature which allows you to send failed messages to another queue which is a DLQ. So that's one of the one of the cool features of SQS. Should we go through and run through the highlight features of SQS quickly? Where would you start? Yeah I think so.

00:06:30

Another interesting feature is DLQ. We already mentioned it. It's something that needs to be enabled and we'll discuss a little bit more how to enable that but it's very easy to have it built in and this is very convenient because it's very common that you define a number of messages types in your application then your code evolves eventually you might be introducing a bug in the code that is processing a job and what happens is that if your job if your worker is always crashing then you're not going to be able to process that message ever so rather than keep retrying it indefinitely it will eventually be moved to a DLQ somebody can investigate and then when you realize what's the problem you fix the bug you can easily reingest from the DLQ and actually process the message so this is actually a very critical feature that I think most applications using IQ should avail of. Another interesting detail is that the protocol of Sqs is not one of the common protocols generally seen in other queuing systems like RabbitMQ or ActiveMQ that uses protocol like AMQP or MQTT. In the case of Sqs the protocol is HTTP. I don't think it makes a huge difference at the end of the day because the way you interact is through the SDK so you don't get to really work at the protocol level but there might be different features and different characteristics in terms of performance because of the underlying protocol so that that might be interesting to know for some people that are coming from other queuing systems. Then we also have a server-side encryption so messages are encrypted in transit and I suppose also they are stored encrypted. We have message delays which basically allows us to configure in different ways how and when the message should appear in the queue. We'll mention a few examples later on. The other very interesting thing is that Sqs is durable and available pretty much by default, also scalable. That means for instance if we look in contrast Kinesis, with Kinesis you need to do a little bit of capacity planning. You need to understand how many shards you need to provision and that's generally based on what is the throughput that you want to achieve. With Sqs you don't have to worry about all the stuff. Queues will automatically scale for you and you don't need to pre-provision any of that stuff. In general I would say that the biggest feature of Sqs is that it is a very simple, true to its name, a very simple queuing system and therefore it's very easy to integrate in most applications and you get very good performance basically straight away without having to go crazy with configuration. Is there anything else worth mentioning? Maybe, I don't know, some interesting integrations with other services. What do you think? Yeah, for sure.

00:20:25

With Lambda, there's something called an event source mapping. It's the same part of the Lambda service that's also used with Kinesis and Kafka sources and DynamoDB streams. But event source mapping is essentially a consumer for SQS that is managed for you within the Lambda service, and it pulls those messages for you. So we mentioned how SQS integrates with other services on the producer side. On the consumer side, it basically doesn't integrate with anything because you have to pull messages out of it. But the exception is Lambda because it does that for you. So one of the interesting things that I came across with Lambda and SQS is how it scales differently than other Lambda sources. So if you're expecting that if you've got, we talked about the batch processing workload, if you've got many, many containers or many Lambda instances running and they're taking a long time to process SQS messages, some type of machine learning workload running in Lambda might take 90 seconds to process an event, for example. The event source mapping is only going to scale to 60 concurrent instances per minute. And this is dramatically different to other event sources where you, I mean, if you call invoke Lambda, you can get a thousand running instantly and you can get another thousand every minute. And that scales really fast. But with SQS, you can't scale that way. And even if you use provision concurrency, which I tried, it's still 60 per second to consume your SQS messages. So that can be a limit, but it depends on how long it takes to process your messages. Obviously, if your messages are going to be processed in seconds or hundreds of milliseconds, you're still going to be able to process thousands of messages or thousands of batches of messages very quickly. But it's just important to be aware of that. Well, if you've got FIFO queues then as well, you get one batch at a time per message group ID. So that's, I suppose that's probably intuitive, but if you've got five different message group IDs, then you're going to have a maximum of five consumers. There's also some interesting configuration options like the batching. So you can configure if it should invoke your Lambda after a predefined number of seconds, like every six seconds, for example, or if it had received a certain threshold number of messages, or also just based on the payload size. So the number of megabytes that it has accumulated. So that's a whole set of configuration that you get with the Lambda service in SQS. And a really new one is the event filtering, which came out just late last year. And this is kind of interesting because you can filter at the event source mapping level and say, I only want to filter messages matching this pattern. And you can do, you know, JSON filter or a string filter. What that actually means sometimes is that if your consumer doesn't match a filter, you can still end up losing messages because they've been processed by the event source mapping, but they just haven't been sent onto your Lambda because you filter them out. So you have to really think about the semantics there and whether you can and if you want another consumer to be able to pick up that message, you might need to re-architect the message delivery setup. And the last thing I'd say about Lambda is just that cross account Lambdas with an SQS in a different account are also possible, which is really helpful. I wish that was available for all the services, including Kinesis, but that's really helpful for integration across multiple applications when you've got a multi account set up, which is best practice these days, you know, separate account per application, per environment. So if you want to communicate across applications, it's a really good way to do it.

Help us to make this transcription better! If you find an error, please submit a PR with your corrections.