Decoupling

Tue, 20 Aug 2024 04:32:50 GMT

> 어플리케이션 끼리의 결합도를 줄이고 소통하는 법을 알아보자. (결국 버퍼다) - SQS - 큐(queue) 모델 - SNS - pub/sub 모델 - Kinesis - 실시간 스트리밍 모델 # 1. Amazon SQS ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134049_zWVpcmiQO1WnOzxtwV?q=80&s=1280x180&t=outside&f=webp) ## SQS 큐의 종류 ### 1. 표준 큐 - 대역폭, 그리고 큐의 크기에 제한이 없고 지연 시간이 낮다. - 메시지 최대 256KB의 크기를 가지고, 기본 4일, 최대 14일까지 보유하고 있다. - 메시지 중복이 발생할 수 있다. - 그리고 최선의 노력으로 메시지를 보내므로 순서는 흐트러질 수 있다. - 소비자는 한 번에 최대 10개까지 가져올 수 있다. - 소비자는 폴링(polling)을 끝내면 메시지를 다시 큐에 넣는다. - 혹은 소비자(consumer)는 DeleteMessage API를 통해 메시지를 지워야 한다. ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134050_2ztvcJaWpvtzW07lIc?q=80&s=1280x180&t=outside&f=webp) - **암호화** - HTTPS API, KMS를 사용하고 그리고 클라이언트에서 암호화를 수행할 수도 있다. - **접근 제어** - IAM 정책 - **SQS 접근 정책 **- S3 정책처럼 SQS 정책을 만들 수 있다. 다른 서비스와 엮기 좋다. ### 2. FIFO 큐 - 선입선출을 사용하여 메시지의 순서를 보장합니다. - 메시지는 한 번만 받아집니다. - 대역폭에 제한이 있습니다. - **그룹 ID**를 지정해 특정 그룹은 특정 소비자에게 가게 할 수 있다. - 메시지 제한 시간 초과를 최대 12시간까지 걸 수 있다. ### SQS 큐 접근 정책 아래는 특정 S3 버킷을 허용해주는 정책이다. ``` { "Version": "2008-10-17", "Id": "__default_policy_ID", "Statement": [ { "Sid": "example-statement-ID", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "SQS:SendMessage", "Resource": "arn:aws:sqs:us-east-2:349630926222:EventFromS3", "Condition": { "StringEquals": { "aws:SourceAccount": "349630926222" }, "ArnLike": { "aws:SourceArn": "arn:aws:s3:*:*:demo-kaonmir-s3-bucket" } } } ] } ``` - **메시지 제한 시간 초과(Invisibility Timeout)** - 소비자가 **ReceiveMessage** 를 호출해 메시지를 받아가면, 메시지는 일정 시간 동안 소비되지 않는다. - **배달 못한 편지 대기열 **- 소비자가 **MaximumReceive** 보다 더 많이 소비하면 해당 메시지를 DLQ(Dead Letter Queue)로 보내버린다. - **지연 대기열 **- 생산자가 메시지를 생산하고 **DelaySeconds** 후에 받을 수 있다. 전체 큐에 적용된다. - **메시지 타이머** - 각각의 메시지 별로 몇 초 후에 받을 수 있다. 클라이언트가 설정한다. - **긴 폴링 -** **WaitTimeSeconds(수신 메시지 대기 시간) **동안 메시지를 받을 수 있다. API 호출 횟수를 줄이고 지연시간과 효율성을 향상시킨다. > 아래 사이트 들어가서 각각의 경우를 모두 머리에 넣자 [Amazon SQS 모범 사례 - Amazon Simple Queue Service](https://docs.aws.amazon.com/ko_kr/AWSSimpleQueueService/latest/SQSDeveloperGuide/working-with-messages.html) ### 요청-응답 시스템 생산자가 메시지를 SQS로 보낼 때, 거기에 대한 응답을 받고 싶을 수 있다. 그러면 생산자는 **ID**와 **Reply to** 메타데이터를 담아서 요청을 보내고 소비자는 소비 후 응답한다. 이때, SQS는 **SQS Temporary Queue Client** 패턴을 통해 임시 큐(reply to)를 만들고 그곳에 응답 메시지를 넣는다. 임시 큐의 생성/삭제는 자동으로 이루어진다. ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134052_N6mFqaOz3VA4XIReH3?q=80&s=1280x180&t=outside&f=webp) # 2. Amazon SNS Pub/Sub 패턴을 통해 하나의 메시지를 여러 구독자한테 전파한다. (SQS에서 큐의 역할을 하는 것이 여기서는 **주제(Topic)**이다. 전파하는 것을 Fan-out이라 부른다. - 이벤트 생성자는 SNS 주제에 메시지를 보낸다. - 해당 주제를 구독하고 있는 구독자들은 모두 메시지를 받는다. - 주제당 최대 10,000,000 구독자를 걸어 놓을 수 있고, 최대 100,00개의 주제를 만들 수 있다. - 구독자는 SQS, HTTP / HTTPS 등이 있다. [구독자는 여기](https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sns-event-destinations.html), [게시자는 여기](https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sns-event-sources.html) 참조 - **암호화** - HTTPS API, KMS를 사용하고 그리고 클라이언트에서 암호화를 수행할 수도 있다. - **접근 제어** - IAM 정책 - **SNS 접근 정책 **- S3, SQS 정책처럼 SNS 정책을 만들 수 있다. 다른 서비스와 엮기 좋다. ### FIFO 주제 - SQS FIFO처럼 메시지를 순서에 맞춰 전파한다. - 구독자는 SQS FIFO 밖에 될 수 없다. - 대역폭에 제약이 있다. ### 메시지 필터링 JSON 정책을 주제에 걸어서 특정 태그만 보내주는 등의 행동을 할 수 있다. ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134053_LTvFI5Oc7d17wXTg4t?q=80&s=1280x180&t=outside&f=webp) # 3. Kinesis [스트리밍 데이터란 무엇인가요? - 스트리밍 데이터 설명 - AWS](https://aws.amazon.com/ko/streaming-data/) 키네시스는 실시간 스트리밍 데이터를 수집, 가공, 분석하는 서비스이다. - Data Stream - Data Firehose - Data Analytics - Video Streams - 다루지 않는다. ### Kinesis Data Stream Kinesis Data Stream은 SQS, SNS처럼 어플리케이션의 결합도를 줄이고 데이터를 소비할 수 있는 형태로 바꾸는 어플리케이션이다. ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134055_64I8SytTVi6IlxQDrL?q=80&s=1280x180&t=outside&f=webp) 1. 먼저 사전에 SQS는 큐, SNS는 주제를 만드는 것처럼 Data Stream은 **스트림**을 만든다. 2. 생산자는 Kinesis에 스트림 데이터를 **최대 1MB**의 BLOB을 가지는 '**레코드**'로 나눈다. 3. 각 레코드는 최대 **1 MB/sec**의 속도로 각 샤드에 들어간다. 4. Kinesis는 **파티션 키**가 같으면 같은 **샤드**에 들어가도록 한다. 5. Kinesis는 샤드에 들어온 순서대로 레코드에 **시퀀스 넘버**를 매긴다. 6. 소비자는 스트림을 **2 MB/sec**의 속도로 읽을 수 있다. 각 샤드 별로 1MB/sec, 1000 msg/sec의 속도를 지원하므로 샤드를 많게 하면 더 많은 데이터를 스트림할 수 있다. 데이터 스트림은 최대 1MB 단위의 레코드로 쪼개져 샤드에 들어가므로 다시 합쳐질 때는 순서 정보가 필요하다. 읽기 옵션은 두 가지인데, 하나(shared)는 전체 소비자들을 합쳐서 최대 2MB/sec의 속도를 제공하는 것이고, 나머지(enhanced)는 각자 최대 2MB/sec의 속도를 제공하는 것이다. 당연히 후자가 비싸다. - 한번 Kinesis로 들어온 데이터는 지울 수 없고 파티션별로 순서가 유지된다. - Kinesis의 데이터는 기본 하루에서 최대 365일까지 보관된다. - 가격은 샤드의 수에 따라 부과한다. ### Kinesis Data Firehose 레코드 단위로 쪼개진 데이터를 변환하고 합쳐서, 큰 batch 데이터로 만든 다음, 저장하는 역할을 한다. ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134057_0jZLYmwl7lnjkooRg0?q=80&s=1280x180&t=outside&f=webp) 1. 레코드를 각각 읽는다. (주로 Data Streams에서 읽는다.) 2. (옵션) 람다 함수를 통해 레코드를 변환한다. 3. 변환한 레코드를 모아 크게 만들어 저장한다. 4. (옵션) 만약 저장에 실패한다면 S3 백업 버킷에 그 데이터를 저장할 수도 있다. 5. (옵션) 아님 모든 데이터를 저장할 수도 있다. Data Firehose는 관리가 필요없고, 자동으로 확장하는 서버리스 서비스이다. Firehose를 지나는 데이터에 대해서만 청구하고 다양한 데이터 포맷과 압축, 변환을 지원한다. 거의 실시간 스트림을 지원한다. '거의'인 이유는 다음과 같다. - 배치(batch)가 꽉 찰 때까지 최소 60초는 기다려야 한다. - 혹은 배치가 최소 32MB가 될 때까지 기다려야 한다. ### Kinesis Data Streams vs Firehose **Kinesis Data Streams** - 데이터를 소비할 수 있게 변환함 - 직접 코드 작성, 실시간(~200ms) - 확장 가능 - 하루에서 365일까지 데이터 보관 **Kinesis Data Firehose** - 스트리밍 데이터를 받아 다른 스토리지에 저장 - 완전 관리, 거의 실시간 - 자동 확장 - 데이터 보관 X ### Kinesis Data Analytics SQL 문법을 이용해 실시간 데이터를 분석하는 완전 관리형 서비스이다. 자동 확장이 가능하고 시간 연속적인 분석이나 실시간 랭킹 등에 사용된다. ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134059_bdBtxHneoy39tazrym?q=80&s=1280x180&t=outside&f=webp) --- # 4. SQS vs SNS vs Kinesis ![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134100_p3huEqHBiymLn2Z5m8?q=80&s=1280x180&t=outside&f=webp) # 5. Amazon MQ SQS와 SNS가 등장하기 이전부터 이런 서비스는 존재해 왔다. 온프레미즈로 사용하던 MQTT나 AMQP 등을 최대한 변경 없이 클라우드에 이식하기 위해서 Amazon MQ를 사용한다. Amazon MQ는 Amazon MQ Broker를 통해 외부 클라이언트와 소통하고 내부 스토리지에 저장한다. 아래와 같은 특징이 있다. - SQS/SNS 만큼 확장이 잘 되진 않는다. - 특정 기계에서 돌아가며 실패에 대한 가용성이 높다. - 큐(SQS)와 주제(SNS) 특징을 모두 가지고 있다. 가용성이 높은 이유는 브로커가 실행되고 있는 AZ 말고 다른 AZ에도 브로커를 두고, 실패가 생기면 곧바로 대기 중이던 브로커랑 연결한다. ### 실습 1. Data Stream에 스트림 생산하고 소비하기 ``` # 레코드를 Kinesis에 넣는다.(signup, login, logout) aws kinesis put-record --stream-name Demo --partition-key user1 --data "signup" --cli-binary-format raw-in-base64-out aws kinesis put-record --stream-name Demo --partition-key user1 --data "login" --cli-binary-format raw-in-base64-out aws kinesis put-record --stream-name Demo --partition-key user1 --data "logout" --cli-binary-format raw-in-base64-out # Kinesis 정보를 확인한다. aws kinesis describe-stream --stream-name Demo # 특정 샤드에 있는 스트림을 소비한다. aws kinesis get-shard-iterator --stream-name Demo --shard-id --shard-iterator-type TRIM_HORIZON # Shard Itorator를 가져온다. aws kinesis get-records --shard-iterator # 레코드들을 가져온다. ```