Develop/서버

메세지 큐 시스템: SQS,Worker,Cron,Queue API Server

안다희 2023. 3. 12. 18:58
728x90

 

메세지 큐 시스템: SQS,Worker,Cron,Queue API Server

목표

- 대량의 푸시를 Main Server 영향 가지 않도록 [정해진 시간에,  따로, 안전하게] 보내기

: 유저 경험 최적화🔥

: DB 부하 줄여 비용 절감🔥

 

현재 문제 상황

: Main Server에서 [DB에게 무리한 데이터를 요청]하고 [무거운 로직을 메인서버에서 돌려] 사용자에게 푸시를 보내는 과정에서 부하가 발생하여, [비용이 들고] [유저 경험을 안좋게] 만든다.

 

문제점: [DB에게 무리한 데이터를 요청]

해결법: DB에게는 최대한 심플하게 데이터 요청

where절에 많은 요청 금지. 최대한 select만 해서 데이터 가져오고, 나머지 데이터 필터링은 (DB보다 값싼) 인스턴스 안에서 하자.

 

문제점: [무거운 로직을 메인서버에서 돌려]

해결법: 메인 서버가 아닌 Worker 서버에게 무거운 로직 실행하도록 넘긴다.


용어설명

Worker

: 일하는 공간

 

Queue API Server

: 작업 주문을 받는 공간, 주문서를 받고 워커에게 넘겨줌

 

SQS

: 작업 메시지 담는 공간, 주문서를 모아 놓은 공간

 

Cron

: 시간별로 처리하는 공간


솔루션 아키텍쳐

참고) Main Server에서는 요청이 들어오는대로 데이터 반환,업데이트가 필요한 API만을 담당한다.

 

- 구현해야 하는 기능은 정해진 시간에 대량의 푸시를 보내는 것인데, 이 작업을 Cron, Queue API Server, SQS, Worker를 이용해 구현한다.

 

1) Cron에서는 정해진 시간에 Queue API Server로 요청 트리거를 보낸다. (즉각 응답을 반환해야 하지만, 그 안에 유의미한 반환값이 있을 필요는 없다. Worker에서 비동기로 작업이 진행되기 때문에, 응답은 대충 성공했다고 반환하기만 하면 된다.)

 

2) Queue API Server 내, 각 API에서는 큐에 요청을 적재하는 작업을 한다.

 

3) 큐 서비스는 AWS에서 제공하는 SQS(Simple Queue Service)를 사용한다.

 

4) WorkerSQS를 구독하고 있다. 큐에 요청이 적재되는 순간, 이를 캐치해서 해당 요청을 진행할 수 있다.

 

5) Worker에서는 대량의 푸시 보내기 작업을 진행한다. (Main Server가 아닌 Worker에서.)

 

6) 대량의 푸시를 보내기 위해서는 User의 정보를 가져와야 하므로, RDS(Relational Database Service)에게 요청한다. 이 때, where절은 최대한 생략하고 select만 해서 심플하게 가져온다.

 

7) 가져온 User에서 탈퇴유저 제외, 푸시를 활성화 한 사람들 제외 등등의 필터링을 Worker에서 진행한다. Push 보내기도 마찬가지로 Worker에서 진행한다.

 

8) [더 나아가기] Push를 보내는 인스턴스도 따로 만들어서, 관심사를 분리할 수도 있다. 7에서 Push 보내는 작업을 Worker가 아닌 전용 Push서버에서 진행하는 것이다. (아키텍쳐 우하단에 회색박스로 가린 부분!)


요약하자면, 무거운 비동기 로직은 Main Server 가 아닌, Worker에게 맡긴다는 것이다!


👍Good

- 유저 경험 최적화🔥

: Worker에서 문제가 생겨도 Main Server에 영향 가지 않는다. (마이크로 서비스)

: 무거운 비동기 로직을 Worker에서 전담한다.

 

- DB 부하 줄여 비용 절감🔥

: 꼭 필요한 select문만 최대한 활용하여, 값비싼 DB에게 일을 시키지 않는다.

: SQS 설계 목적 중 하나는 아니지만, 우리 서비스에 도움되는 글!

 

⚠️Worker 주의

- 큐에 걸맞는 작업만 받아서 처리한다.

  : 큐에 적재하여 비동기로 처리해도 되는 로직들만 요청 보내자!


SQS란?

완전 관리형 메세지 대기열.

 

- 초기 비용 없이 소프트웨어를 관리하거나 인프라를 유지하지 않고 오버헤드를 제거할 수 있습니다. 

: AWS가 제공하는 SQS 사용 -> 비용절감

 

- 메시지를 누락하거나 다른 서비스를 가용 상태로 유지하지 않고도 처리량에 관계 없이 대량 데이터를 안정적으로 전송할 수 있습니다.

: 메인서버 내에서 동작하지 않고 아예 따로 관리하여 안정적 전송

 

- 민감한 데이터를 애플리케이션 간에 안전하게 전송하고 AWS Key Management를 사용하여 키를 중앙 집중식으로 관리할 수 있습니다.

: 민감한 데이터는 AWS에서 중앙 집중 관리

 

- 사용량에 따라 탄력적이고 비용 효율적으로 확장할 수 있으므로 용량 계획 및 사전 프로비저닝에 대해 걱정할 필요가 없습니다.

: 사용량에 따라 AWS에서 쉽게 관리하게 해줌. 미리 걱정X


SQS vs RabbitMQ vs Kafka

1) Amazon SQS

: 구축이 쉽고 관리가 용이하다.

 

2) RabbitMQ

: 백그라운드 작업이나 PDF 변환, 파일 검색 또는 이미지 확장과 같은 장기 실행 작업도 처리할 수 있습니다. 즉, 장시간 실행되는 태스크, 안정적인 백그라운드 작업 실행, 애플리케이션 간/내부 통신/통합이 필요할 때 RabbitMQ를 사용합니다.

: RabbitMQ는 메시지 보존이 부족하고 소비자의 확인 메시지가 보장되므로 강력한 메시지 브로커인 응용 프로그램 중재자에 더 적합

: Consumer-> Exchange -> binding rules -> queue -> producer

 

: ex) 티모바일, RUNASTIC

 

3) Kafka

: 높은 처리량. 상당히 확장 가능한 시스템이며 일괄 처리로 메시지를 보내려는 경우(좋은 메시지 처리량을 갖기 위해) 높은 워크로드에 적합하다.

: 같은 토픽 파티션의 메세지는 순서보장. 그러나 같은 토픽 내 여러개의 파티션 사이에서 처리 순서는 보장하지 않는다. (라운드 로빈 메세지 분배 시스템 때문)

:  데이터 허브 역할을 하기도 함.

: Kafka의 메시지 보존은 메시지 로거 또는 거대하고 빠른 데이터 스트리밍 서버에 적합합니다. 실패 후 메시지를 다시 시도해야 하는 책임은 소비자에게 있으므로 Kafka는 메시지가 성공적으로 전달되었는지 여부를 신경 쓰지 않습니다. 이것은 추가 구현을 덜어주고 데이터 재생 및 쿼리에 중점을 둡니다.

: Consumer -> broker -> partition -> Consumer (큐 구현x)

: ex) 카카오, 라인, 넷플릭스, 링크드인

 

 

참고링크

- https://escapefromcoding.tistory.com/705

- https://engineering.linecorp.com/ko/blog/how-to-use-kafka-in-line-1/

- https://colevelup.tistory.com/16

- https://velog.io/@xgro/%EB%A9%94%EC%84%B8%EC%A7%80-%EB%B8%8C%EB%A1%9C%EC%BB%A4%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%8B%9D-%ED%86%B5%EC%8B%A0

- https://haloworld.tistory.com/146

- https://yoonbing9.tistory.com/130

- https://angryfullstack.tistory.com/entry/Queue-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-Aws-SQS-RabbitMQ-Kafka-%EB%8A%94-%EC%96%B4%EB%96%A4-%EB%AA%A9%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%8D%A8%EC%95%BC%ED%95%98%EB%82%98%EC%9A%94


!잘못된 내용이 있다면 댓글로 남겨주세요 :)