애플리케이션 커뮤니케이션의 두 가지 패턴
동기 커뮤니케이션: 애플리케이션끼리 직접적으로 연결된다. 물건 주문 서비스->배달 서비스와 같이 직접적으로 연결된 서비스
비동기 혹은 이벤트 기반 유형: 대기열(Queue)등으로 불리는 미들웨어가 애플리케이션들을 연결한다. 구매서비스는 '누군가 물건을 구매했으니 이를 대기열에 포함시키겠다' 라고 하고 끝이다. 배송서비스는 대기열에 최근 구매 내역이 있는지를 확인하고 해당 요소를 반환받으면 배송서비스가 시작된다. 서로 직접적으로 소통하지 않는다.
어플리케이션 간의 동기화는 때때로 문제가 될 수 있다. 한 서비스가 다른 서비스를 압도하는 경우 운용이 정지되기 때문에 트래픽이 갑자기 급증하거나 아무것도 예측할 수 없을 때 일반적으로 애플리케이션을 분리하고 분리 계층을 확장하는 것이 좋다.
대기열 모델의 경우 SQS, pub/sub 모델의 경우 SNS, 실시간 스트리밍을 하고 대용량 데이터를 다룬다면 Kinesis로 분리 가능하다.
👉🏻 생산자는 SDK (SendMessage API)를 사용하여 필요한 정보를 담아 메시지를 보낸다.
👉🏻 소비자는 EC2 인스턴스, 온프레미스 서버, AWS Lambda가 될 수 있다.
ASG에서 CloudWatch 지표중에 ApproximateNumberOfMessages(대기열의 길이) 지표로 알람을 만들어 대기열의 길이가 특정 수준을 넘어가면 오토스케일링하도록 설정할 수 있다.
예를 들어 비디오를 처리하는 애플리케이션이 있다고 하자. 프론트엔드에서 비디오를 처리하고 S3에 저장하면 웹사이트의 속도가 느려질 수 있다. 대신 애플리케이션을 분리해 파일 처리 요청과 실제 파일 처리가 서로 다른 애플리케이션에서 발생할 수 있도록 한다. 파일 처리 요청을 받을 때마다 SQS 대기열로 메시지를 전송하는 것이다.
HTTPS API를 사용해 메시지를 보내고 생성함으로써 전송 중 암호화 가능
KMS키를 사용해 미사용 암호화를 얻고 원한다면 클라이언트 측 암호화를 할 수도 있다.
액세스 제어를 위해 IAM 정책은 SQS API에 대한 액세스를 규제할 수 있다.
S3버킷 정책과 유사한 SQS 액세스 정책도 있다. 다른 서비스가 SQS 대기열에 S3이벤트 같은 것을 쓸 수 있도록 허용하려는 경우에 유용하다.
Standard큐와 FIFO큐를 선택할 수 있다.
Standard큐는 최소 한 번 전달, 메시지 순서가 유지되지 않음
FIFO큐는 선입선출 배달, 메시지 순서가 유지되며 정확히 한 번 처리한다.
누가 이 대기열에 액세스할 수 있는지 정의한다.
메시지를 전송할 수 있고 메시지를 받을 수도 있다.
처음엔 메시지가 없고 메시지를 작성하면 Messages available에 1이라고 뜬다. Poll for messages를 클릭하면 메시지를 수신할 수 있다.
수신된 메시지ID를 누르면 메시지의 해시, 발신자, 메시지를 받은 횟수, 바이트로 된 사이즈 등의 메타데이터를 볼 수 있다.
적절한 시간 내에 메시지를 처리하지 않으면 30초가 지나 메시지는 다시 대기열로 돌아가 Message Count가 늘어난다.
SQS > Queues > 원하는 큐 선택 > Edit을 누르면 모든 설정을 편집할 수 있다.
SQS > Queues > 원하는 큐 선택 > Purge 클릭
이 방법은 개발할 때는 유용한데 프로덕션에서는 하면 안됨.
소비자가 ReceiveMessage 요청을 하면 대기열에서 메시지가 반환되고 가시성 시간 초과가 시작된다.
기본적으로 메시지 가시성 시간 초과는 30초다. 30초 안에 메시지가 처리되어야 한다.
30초 안에 메시지를 처리하면 동일한 혹은 다른 소비자가 메시지 요청 API를 호출해도 메시지가 반환되지 않는다.
가시성 시간 초과 기간 내에서는 그 메시지는 다른 소비자들에게 보이지 않는다.
가시성 시간 초과가 경과되고 메시지가 삭제되지 않으면 메시지는 대기열에 다시 들어간다.
그럼 다른 호출자가 ReceiveMessageAPI를 호출하면 이전의 메시지를 또 받게 된다.
소비자가 메시지를 처리하는 데 시간이 더 필요하면 ChangeMessageVisibility라는 API를 사용해 SQS에 시간이 더 필요하다고 알려 다른 호출자에게 메시지가 보이지 않도록 요청할 수 있다.
✨가시성 시간 초과는 애플리케이션에 합당한 값으로 설정하고 소비자가 그보다 더 시간이 필요하면 ChangeMessageVisibility API를 요청한다!
소비자가 대기열에 메시지를 요청하는데 대기열에 아무것도 없다면 메시지 도착을 기다리게 된다. 이것을 롱 폴링이라고 한다.
롱 폴링을 하는 두가지 이유
1) 지연시간 줄이기
2) SQS로 보내는 API호출 숫자 줄이기
작동방식
롱 폴링은 1초~20초 내로 구성이 가능하다. 더 길어질수록 좋다.
대기열에 도착한 순서대로 메시지를 내보낸다.
순서를 확실히 보장하기 때문에 이 SQS 대기열의 처리량에는 제한이 있다.
메시지를 묶음으로 보낸다면 처리량은 초당 3,000개이며 묶음이 아니라면 초당 300개의 메시지를 처리한다.
중복을 제거하도록 해주는 기능이 있어 정확히 한 번만 보낼 수 있게 한다.
메시지의 순서를 유지할 필요가 있을 때 FIFO 대기열을 사용하면 된다.
SQS로 너무 많은 메시지를 보내지 않도록 처리량 제한도 가능하다.
📍 SNS에서 구독자에게 게시할 수 있는 것들
1. 이메일 보내기
2. SMS 및 모바일 알림 보내기
3. HTTP 또는 HTTPS 엔드포인트로 직접 데이터 보내기
4. 메시지를 SQS 대기열로 보내기
5. Lambda에 보내기
6. Firehose를 통해 데이터를 S3나 Redshift로 보내기
📍 SNS로 데이터를 보낼 수 있는 AWS 서비스들
1. CloudWatch 경보
2. Auto Scaling 그룹알림
3. CloudFormation State Changes Budgets
4. S3버킷 DMS
5. Lambda
6. DynamoDB RDS이벤트 등
다수의 SQS 대기열로 메시지를 보내려 할 때 모든 SQS 대기열에 개별적으로 전송하려고 하면 문제가 발생할 수 있다. 어플리케이션 충돌이 발생해 실패하거나 SQS대기열을 추가하게 될 수도 있다.
개념은 SNS 토픽으로 한 번 메시지를 전송하고 원하는 만큼 SQS 대기열을 SNS토픽에 구독시키는 것이다.
이는 완벽하게 분리된 모델이고 데이터 손실이 없다. SQS로 데이터 지속성, 지연 처리, 작업 재시도 등의 효과를 얻을 수 있다. 이 패턴으로 시간이 지날수록 SQS대기열을 구독자로 더 추가할 수 있다. 그러기 위해 SQS 대기열 접근 정책을 SNS 토픽이 대기열에 쓸 수 있도록 허용해둬야 한다.
한 리전의 SNS토픽이 다른 리전의 SQS 대기열에 메시지를 보내는 것이 가능하다.
📍 사용사례
S3 이벤트 규칙에는 제한이 있는데, 예를 들어 객체가 생성되고 객체의 접두사가 images/ 처럼 이벤트 형식이 조합될 경우 오직 한 개의 이벤트 규칙만 존재할 수 있다.
이때 여러 개의 대기열로 S3 이벤트 알림을 보내고 싶으면 SNS를 사용해 팬아웃 패턴을 적용할 수 있다.
토픽의 메시지에 순서를 부여한다.
생산자가 메시지를 1,2,3,4 순서로 메시지를 보내면 구독자는 SQS FIFO 대기열이 될 수밖에 없고(SQS 표준도 됨) 순서대로 메시지를 받는다.
FIFO와 Standard중 선택한다.
1) Standard : 최선의 메시지 정렬, 최소한 한번의 메시지 전달, 초당 게시 횟수 측면에서 최고의 처리량을 얻을 수 있음. 다양한 구독대상들(SQS, Lambda, HTTP, SMS, 이메일)
2) FIFO : 엄격히 메시지 순서 유지, 초당 300번까지 게시 가능한 처리량, SQS FIFO 대기열만 구독가능.
FIFO 선택할 경우 Topic명이 .fifo로 끝나야한다.
토픽의 메시지를 암호화 할 수 있다.
Access policy을 통해 누가 SNS Topic으로 전송할 수 있는지를 정의한다.
나머지는 일단 두고 생성 완료한다.
토픽을 선택하고 Create subcription을 눌러 구독을 생성한다.
✨프로토콜을 선택해야 하는데 Kinesis Data Firehose, SQS, Lambda, Email, Email-JSON, HTTP, HTTPS, SMS 중에 선택한다.
그리고 엔드 포인트(이메일이면 이메일주소)를 입력한다.
Subscription filter policy를 설정해서 필터링된 메시지만 받게 할 수도 있다.
이메일 주소를 입력했다면 이메일로 온 메일을 통해 구독을 승인해줘야 한다.
토픽을 선택하고 오른쪽 상단의 Publish message를 선택해 메시지를 생성한다.
실시간 데이터
- 애플리케이션 로그
- 계측
- 웹 사이트 클릭 스트림
- IoT 원격 측정 데이터 등
데이터가 빠르게 실시간으로 생성된다면 모두 실시간 데이터 스트림으로 간주한다.
Kinesis는 네 가지 서비스로 구성되어 있다.
레코드는 파티션 키와 최대 1MB 크기의 데이터 블롭으로 구성된다.
파티션 키는 레코드가 이용할 샤드를 결정하는 데 사용되고 데이터 블롭은 값 자체를 의미한다.

선택하기 전 과금 정보를 확인할 수도 있다.
샤드마다 시간당 부과되는 달러가 표시된다.
Data STream으로 PUT을 보내거나 데이터를 전송하는데 부과되는 비용도 볼 수 있다.
On-demand와 Provisioned 중에 고른다.
1) 온디맨드 모드에서는 용량을 걱정하지 않아도 알아서 조정해준다.
2) Provisioned에서는 제공 샤드를 설정해야 한다. 샤드 추정도구로 초당 얼만큼의 레코드를 보내는지, 레코드 크기, 소비자 몇명인지에 따라 추정가능하다.
선택을 하면 제공되는 쓰기 용량과 읽기 용량을 확인할 수 있다.
둘 다 프리티어는 없다.
생성을 완료한다.
Producers : Kinesis Agent, AWS SDK, Amazon KPL 중 하나를 선택해 Kinesis Data Stream으로 데이터를 스트리밍할 수 있다. (CloudShell을 통해 SDK 사용 가능)
Consumers : Kinesis Data Analytics, Kinesis Data Firehose, Kinesis Client Library(KCL), 람다(Lambda) 등이 될 수 있다.
Configureation 탭에서 샤드 개수를 수정해 스트림을 조정할 수도 있다.
CloudShell에서 aws --version을 입력해 현재 버전에 맞는 명령어를 사용한다.
클라우드 쉘은 나의 IAM 자격 증명이 자동으로 구성되어 알아서 된다.
aws kinesis put-record \
--stream-name my-kinesis-stream \
--partition-key my-key \
--data "SGVsbG8sIEtpbmVzaXMh" # Base64 인코딩된 "Hello, Kinesis!"
스트림 이름과 데이터를 보내고자 하는 파티션 키, 데이터를 입력하여 전송한다.
--data "$(echo -n 'Hello, Kinesis!' | base64)"
Base64 인코딩 되지 않은 평문으로 보내려면 이런 식으로 보낸다.
aws kinesis get-shard-iterator \
--stream-name my-kinesis-stream \
--shard-id shardId-000000000000 \
--shard-iterator-type TRIM_HORIZON
SDK를 통해 데이터를 읽어오려면 어떤 샤드에서 읽어오는지 ShardID를 정확히 명시해줘야 한다. (KCL을 사용한다면 라이브러리가 다 처리해준다.)
TRIM_HORIZON은 스트림의 맨 처음부터 읽을 것이라는 뜻이다. LATEST 타입을 선택하면 CLI 명령을 실행하는 순간부터 그 이후 보내지는 레코드만 읽어온다.
엔터를 치면 샤드 반복자(Shard Iterator)가 나온다. 샤드 반복자는 레코드를 소비하는데 다시 사용될 수 있다.
aws kinesis get-records --shard-iterator YOUR_ITERATOR_VALUE
여기에서 샤드 반복자(Shard Iterator)를 YOUR_ITERATOR_VALUE 위치에 입력해준다.
엔터를 누르면 여러 레코드가 나온다. 데이터는 base64로 인코딩 되어 나타난다.
그 다음 NextShardIterator에 있는 값을 사용해서 그 지점부터 다음에 소비할 수 있다.
데이터의 소스를 선택한다. Kinesis Data Streams가 가장 일반적이며 CloudWatch, IoT Core, SDK로 앱에서 직접 전송 등의 방법도 가능하다.
데이터를 보낼 곳을 지정한다.
전송 스트림 이름은 자동 입력된다.
레코드 변환 및 형식 섹션:
1) 람다를 선택해 람다로 레코드 변환, 필터, 압축해제, 형식 변환을 수행할 수도 있다.
2) Convert record format을 선택하면 데이터를 어디로 보내느냐에 따라 데이터 형식을 파켓이나 ORC로 변환할 수 있다.
Parquet(파켓) & ORC란?
대용량 데이터를 효율적으로 저장하고 분석하기 위한 컬럼 기반 저장 포맷
특히 Hadoop, Spark, AWS Athena, BigQuery 같은 빅데이터 처리 환경에서 많이 사용
전송지가 S3라면 데이터를 저장할 접두사와 에러를 출력할 접두사를 설정할 수도 있다.
버퍼 힌트 섹션에서 버퍼를 설정할 수 있다.
버퍼는 데이터를 대상에 전송하기 전에 쌓아두는 기능이다.
1) Buffer Size : 버퍼 사이즈만큼 데이터가 버퍼에 차기를 기다렸다가 다 차면 대상에 데이터를 전송한다.
데이터를 빨리 보내는 게 중요하면 버퍼 size를 작게 설정, 효율을 높이고 싶으면 크게 설정.
2) Buffer interval: 버퍼가 차지 않는다면 언제까지 기다렸다가 전송하는 지를 설정한다. 기간이 지나면 다 차지 않았어도 전송해버린다.
데이터 압축이나 레코드 암호화 설정도 필요에 따라 하면 된다.
고급설정에서는 권한 설정을 위해 IAM Role을 생성한다.
| 특징 | SQS (Simple Queue Service) | SNS (Simple Notification Service) | Kinesis Data Streams |
|---|---|---|---|
| 주요 개념 | 메시지 큐 (Queue) | 퍼블리시/구독 (Pub/Sub) | 실시간 데이터 스트리밍 |
| 데이터 흐름 | 1:1 (Producer → Consumer) | 1:N (Producer → 여러 Subscriber) | 1:N (Producer → 여러 Consumer) |
| 메시지 전달 방식 | 메시지 하나씩 전달 & 삭제 | 여러 구독자에게 동시에 전송 | 지속적인 데이터 스트림 처리 |
| 데이터 보관 | 소비 후 삭제 (최대 14일) | 보관 X (즉시 전달) | 보존 기간 내(최대 365일) 재처리 가능 |
| 사용 사례 | 비동기 작업 처리 (예: 주문 처리, 백그라운드 작업) | 다중 시스템 알림 (예: 장애 감지, 이메일/SMS 알림) | 실시간 로그 분석, IoT 데이터 수집 |
| 주요 특징 | ✔ FIFO 지원 가능 (순서 보장) ✔ 개별 메시지 처리 | ✔ 여러 프로토콜 지원 (Lambda, HTTP, SMS, Email 등) | ✔ 실시간 대용량 데이터 처리 ✔ 데이터 재처리 가능 |
| 예제 사용처 | EC2 → SQS → Lambda (비동기 처리) | CloudWatch → SNS → Email (알림 시스템) | IoT 센서 → Kinesis → 분석 (실시간 데이터 분석) |
애플리케이션을 클라우드에 마이그레이션하는 경우에는 SQS, SNS 프로토콜 혹은 API를 사용하기 위해 애플리케이션을 다시 구축하고 싶지 않고 MQTT, AMQP 등과 같은 기존에 쓰던 프로토콜을 사용하고 싶을 수 있는데 이때 Amazon MQ를 쓰면 된다.
특정 리전 내의 두 개의 AZ가 있다.
1번 AZ는 ACTIVE 상태이고 2번 AZ는 STANDBY상태이다.
두 AZ에 MQ Broker를 추가하고 백엔드에 Amazon EFS를 둔다.
두 MQ Broker가 같은 데이터를 가질 수 있기 때문에 장애조치가 올바르게 시행된다.