-
Comparing AWS messaging service - SNS vs SQS (AWS SNS vs SQS 비교, Slack 메세지 보내기 적합한 파이프라인 선택하기)Data Engineering/AWS, Spark 2023. 1. 18. 15:28728x90반응형
AWS SNS, SQS is the famous services which help to send event messages. Here, I will look through those two services and find which one is best for my pipeline. I'm writing this post for the pipeline that sending a Slack notification from AWS Elastic Beanstalk and S3 through Lambda function. Therefore, please be aware all comparision, listing, describing something in this post will focus on this specific purpose. For example, there can be more outstanding features of AWS SNS, but I'll list or omit the features depending on the importance for my task.
광고 이벤트 서버를 위해 Elastic beanstalk을 사용하였고, log파일 저장소로 S3를 사용하여서 두 개의 서비스와 slack을 연동하기 위한 방법을 찾아보던 중 SNS와 SQS라는 서비스를 접하게 되었다. 소스에서 SNS를 통해 람다로 메세지를 보내거나 SQS를 한번 더 호출한 이후 람다를 호출하는 등 이벤트 메세지를 보내는 파이프라인이 다양했는데, 내가 빌드하고자하는 상황에는 무엇이 최적인지 선택하기 위해 각 파이프라인이 어떻게 다른지 비교해보았다. 따라서 아래에 적혀져있는 장단점 비교나 특징 나열 등은 모두 S3/EB에서 슬랙 (정확히는 람다)로 이벤트 메세지를 보내기 위한 목적에 초점이 맞춰져있음을 유의하고 읽기 바란다.
1. AWS SNS (Simple Notification Service)
SNS is AWS's managed messaging service. The service has the following features:
- Fan out : With the concepts named 'subscribe' and 'topic', the service supports to deliver messages from N sources to N destinations
- A2P (Applications to People) service: Destinations of event messages can be Emails, SMS
If many destination subscribes a topic, SNS copies one message and deliver it asynchronously. Any message published to a topic can be immediately received by all of the subscribers.
Also, no charges for deliveries to Lambda or SQS.
SNS의 가장 큰 특징은 다음 두 가지이다.
- '주제'와 '구독'이라는 개념을 통해 여러 소스에서 발생한 메세지를 여러 목적지로 전달하는 기능 제공 (Fan out)
- 이메일, SMS등 사람으로 직접 메세지를 전달하는 'A2P' 서비스 제공
SNS의 경우 하나의 메세지를 복제하여 여러 목적지로 전달하는 작업을 비동기적으로 처리한다. 또한, 여러 소스에서 메세지를 입력받을 수도 있는데, 이는 FIFO로 처리한다.
메세지 전달이 주요 기능이므로 Lambda나 SQS로 메세지를 전달할 경우 추가 비용이 발생하지 않는다 (Lambda 또는 SQS 비용만 발생). Kinesis로의 전달은 요금이 발생하니 요금표를 확인하는 것이 필요하다.
2. AWS SQS (Simple Queue Service)
SQS is AWS managed message queue service. Message queue is a form of middleware which stores messages temporary to enable independent application-to-application communication. The biggest difference with SQS/ Lambda is, the two services are called when event happens but SQS usues polling - a consumer of messages keeps monitoring queue to check whether there's new msg or not.
This means the main puropose of SQS and SNS is different. SNS is used to deliver a message from many sources or to many destinations. On the other hands, SQS is used for reliable, stable message delivery.
SQS는 AWS에서 제공하는 메세지 큐 서비스이다. 메세지 큐란, 프로세스 간에 메세지를 교환할 때 중간에 메세지를 담아놓기 위해 사용하는 미들웨어이다. 즉, 메세지를 안정적으로 받아서 보관하고 전달하는데 초점을 맞춘다. 지금 비교하고 있는 다른 두 서비스와의 가장 큰 차이점은, SNS와 Lambda는 이벤트가 발생하면 메세지를 처리하는 주체가 호출당하는 push방법이 사용되지만, SQS는 메세지를 처리하는 주체(SQS에서 컨슈머)가 큐의 메세지 도착 여부를 확인하는 폴링 방법이 사용된다.
SQS와 SNS의 주요 목적을 비교하자면 다음과 같은 느낌이다.
- SNS: 이벤트가 발생하면 메세지를 여러 곳에 전달
- SQS: 이벤트가 발생하는 순서대로 큐에 담아뒀다가, 하나의 컨슈머가 가져가면 발생한 순서대로 전달해줌
3. Pipeline
I compared below 4 pipelines to choice the best one to send notifications to Slack from EB/ S3.
Fyr, I didn't consider the options to connect SNS/SQS directly to Slack because I wanted to transform the message to make it readable. Also, EB/ S3 doesn't support to send event notification to Slack directly.
EB, S3에서 Slack으로 메세지를 보내기 위해 (정확히는 Lambda) 다음 네 가지 파이프라인을 검토했다. Lambda를 사용하지 않고 바로 Slack으로 보내는 방법이 있기는 한데, 메세지 가독성이 너무 좋지 않아 중간에 Lambda를 끼워넣었다.
1. SNS → Lambda
2. SQS → Lambda
3. SNS → SQS → Lambda
4. Invoke a Lambda function directly
To compare opt 1 and opt 3, we need to check upsides of using SQS. It also can be an criteria to choose the better option btw opt 2 and opt 4.
In my pipeline, using SQS means using a message queue. Comparing with the others, message queue supports more reliable delivering service because each component communicates not with the others' endpoint directly but with messaging queue. So even if one part is unreachable, the other still can interact with the queue. In addition, message expiration in queues is only on consumer's action or retention period. Therefore, we can retry consumer(a Lambda function) with a same event message once it fails.
In other word, below scenarios might happen without SQS:
- If Lambda function fails during handling the first msg, the following msgs can be missed while lambda function rerun the script for the first msg.
- If Lambda function fails after retrying the assigned number of retries, we can't re-drive the msg back.
SQS costs 0.126USD/GB (doc) based on Seoul region. Lambda also guarantee some reliability (at least as much as I need). Moreover, we can additionally improve it by adjusting concurruncy configuration, retry numbers, scaling, dead letter queue... Therefore I decided not to use SQS for my notification pipeline.
옵션 1과 3, 옵션 2와 4를 비교해보면 SQS를 중간에 쓰냐 마냐의 차이다.그렇다면 SQS를 썼을때의 장점이 뭔지를 살펴보자. 위의 파이프라인에서 SQS를 쓰냐 마냐의 차이는 곧 Message queue를 중간에 끼워 넣냐 아니냐의 차이다 (다른 특징들이나 기능들은 SNS, Lambda에서도 모두 어느 정도 제공하는 기능/특징들이므로). Message queue를 쓴다는 것은 결국 메세지 전달의 안정성이 얼마나 중요하냐, 해당 메세지를 얼마나 잃어버리면 안되느냐의 문제로 귀결된다. SQS를 쓰지 않았을 때 최악의 시나리오는 Lambda 함수가 retry 횟수를 초과하고 서도 실패했을 때다. 이벤트가 사라져버리기 때문이다 (하지만 이제는 Lambda도 dead letter queue를 지원한다는...)
사실 replication failure과 같은 상황은 많이 발생하지 않을 거라 기대해서 비용이 크게 예상되지는 않았지만, SQS를 굳이 끼워넣어서 파이프라인의 복잡도를 올려야할 정도로 메세지 전달의 안정성이 중요한 파이프라인은 아니었다. 어차피 이벤트 데이터는 cloudwatch에 남아있을 거고, SQS를 쓴다해도 결국 메세지 전달 실패를 위한 알람을 추가로 설정해야하기 때문이다.
따라서 1차로 해당 파이프라인에 SQS를 사용하지 않기로 결정했다.
Deciding to use SNS is way more simple, because it costs same with not using it. We only need to check if one of the following cases applies:
- When there is more than one source or destination of event messages.
- When there is more than one sources, each source has many destinations and all sources' destinations are same.
- When destinations are people (Email, SMS) (If those're Email, SNE also can be an option)
SNS 사용 여부를 결정하는 것은 훨씬 간단하다. 이벤트를 발생시키는 출처가 여러 군데이거나, 이벤트 메세지를 전달할 목적지가 여러 군데이거나, 둘 다 이거나, 목적지가 Email이나 문자와 같은 플랫폼일 경우 SNS를 사용하는 것이 좋고, 아니라면 굳이 사용할 필요가 없다고 생각된다. 셋 다 해당하지 않기 때문에 SNS도 사용하지 않기로 했다. 하지만 Elastic beanstalk의 경우 Lambda로 바로 이벤트를 보내는 서비스를 지원하지 않기 때문에 어쩔 수 없이 EB → SNS → Lambda → Slack 의 파이프라인으로, S3의 경우 S3에서 Lambda를 바로 호출하는 파이프라인으로 선택했다.
Sending event messages from Elastic Beanstalk to Lambda and S3 to Lambda applies none of those. Finally, it's best to send event message to Lambda directly is best for both services. However, Elastic Beanstalk doesn't support a notification service to Lambda, so below is my final Slack notification pipeline.
- S3 replication job fails → Invoke the connected Lambda function and send an event message to the function → The function runs its script (parse the message and send a notification to Slack)
- Changes in Elastic beanstalk environment's status → Send an event message to SNS → SNS delivers the message to the Lambda function that the EB environment is subscribing to → The Lambda function is invoked and runs its script (parse the message and send a notification to Slack)
728x90반응형'Data Engineering > AWS, Spark' 카테고리의 다른 글