당근마켓의 마이크로서비스 도입
초기 모놀리틱 시스템 구성
- Ruby on Rails, PostreSQL 한대
- Amazon ECS
현재 마이크로서비스 구성
- GO, Nodejs, Python, Java, Kotlin
- Amazon EKS
마이크로서비스 도입의 장점
- API 중심 개발 : 모놀리식은 유저와 직결되는 기능에 초점을 맞추지만, 마이크로서비스는 사내 개발자에게 제공할 API도 설계
- 코드 복잡도 : 모놀리스는 한 서버에서 모든 기능을 구현하므로 코드 복잡도가 크지만, 마이크로서비스는 코드 복잡도가 낮은 여러 서비스로 구성하므로 코드 관리가 쉬움
- 빌드 시간 : 서비스가 크지 않으므로 이슈 트래킹이나 배포에 걸리는 시간이 비교적 짧다
왜 당근마켓은 마이크로서비스 도입을 선택했는가?
- Main DB에 채팅 데이터를 보관했는데, 50%가 인덱스에 할당되었음
- PostgreSQL Vaccume이 일어나면 응답시간이 저하됨
- 가장 많은 사용량을 가진 채팅 데이터를 DB에서 분리하고, 이를 위해 채팅 API까지 전부 분리하기 시작
채팅 마이크로서비스 설계
채팅 마이크로서비스 개발
- 채팅 데이터 분리 : 데이터 재모델링, 마이그레이션
- 기존 API 재구현, LB 단에서 스위칭
DynamoDB와 API
채팅 데이터 분리 시 데이터베이스 선택하기
- 관리형 서비스일 것. 운영 시간 아끼기
- 데이터 용량 확장에 용이할 것. 페타 바이트까지 감당 가능해야함.
→ AWS DynamoDB : 고가용성, 안정성, 오토 스케일링, ms 단위의 빠른 요청
→ 현재까지도 장애 경험 없다고 함..!
DynamoDB를 사용하며 어려웠던 점
- SQL 사용 불가, Query와 Scan API만 사용 가능
- Scan은 데이터를 풀 스캔하므로 비용 때문에 사실상 사용 불가
- Query는 인덱스를 건 Item만 가져올 수 있음
- 인덱스를 잘 두어야 하기 때문에 설계에 대한 고민 많이 필요함!
- 파티션 하나 : 채팅방 하나
- SK로 Message ID를 사용해 최신 순으로 메시지 정렬
- 하나의 채팅방에 동시 접근하는 유저 수는 많아도 1000명 정도이므로 hot partition을 일으키는 처리량 부하까지 가지 않는다
DB를 사용하는 API Server 재구현
- GO로 기존 API를 재구현
- 기존 서버에 강하게 결합된 API는 내부 API로 재구현하고 연동
- 작은 Util 함수까지 테스트 코드 작성하여 검증
- 채팅 통신 프로토콜 (gRPC, WebSocket, Rest API) 수준의 테스트 코드 작성
- 현재 약 1250개의 테스트가 PR 리퀘스트 시에 실행됨
클라이언트와 API 서버 통신 구간
WebSocket을 통한 실시간 메시징 시스템 도입
- 기존 : FCM 기반 REST 폴링, 실시간 응답 x
- 현재 : 웹소켓과 연결된 유저는 FCM 상태와 무관하게 이벤트를 받아서 처리
유저 간 메시지 주고 받기
- 유저가 채팅 시스템에 접속하면 각 채팅 API 서버에 붙어있게됨
- 다른 유저에게 메시지를 주고 받으려면 다른 서버의 유저에 메시지를 전달해야함
- 이때 gRPC로 서버 간 메시지를 주고 받음
ElastiCache - Redis
- 웹소켓을 사용하기 위한 세션 저장소
- 유저가 어느 API 서버에 붙어있는지 확인하기 위함
- 스케일 아웃을 위해 클러스터 모드로 사용, 무상태 서버로 사용 가능
데이터 분석 파이프라인
데이터 분석 파이프라인 재편
- 기존 : RDBMS에 의존하는 분석 파이프라인
- 현재 : DynamoDB의 데이터를 처리하기 위한 분석 파이프라인
DynamoDB 데이터 분석 파이프라인
- DynamoDB의 제약사항 : 풀 스캔 불가
- DynamoDB Stream : DynamoDB에서 발생한 CUD 이벤트를 로깅하고 스트림함. 거의 실시간이므로 어플리케이션에서 액세스해 원하는 처리 가능
- Lambda : 새로운 스트림의 레코드를 감지해서 폴링, 레코드 형식을 KV 형태로 반환, 분석에 필요하지 않은 데이터는 제거
- Firehorse : 이벤트를 버퍼에 받아 S3에 업로드, 이때 버킷 prefix 설정하여 파티셔닝, 압축, 일정 주기로 버퍼 비우기
- S3 & Athena : 스토리 웨어하우스와 데이터 분석
DynamoDB 데이터 분석 파이프라인 Serverless Version
- DynamoDB → Lambda → Firehorse → Raw data
- DynamoDB Stream 활성화 설정
- Firehorse 생성
- 서버리스 프레임워크에서 DynamoDB ARN과 Firehorse ARN 값을 넣어서 스트림 하나씩 배포
다른 서비스와의 통신
채팅 데이터를 다른 서비스에서 활용하기
- fluentbit를 통해 managed kafka로 보냄
- fluentbit : 안정적으로 이벤트를 전달하는 버퍼. 다양한 output(kafka, s3, firehorse 등) 지원. 전송을 보장하므로 output 장애 시에도 이벤트가 유실되지 않음. 0.1코어를 사용하는 초경량 컴포넌트
- kafka : 이벤트 pub sub
'Cloud > AWS' 카테고리의 다른 글
S3에 파일 업로드, 다운로드하는 public API 만들기 (0) | 2024.01.17 |
---|---|
[AWS Session 기록] Key Value NoSQL과 키 디자인 패턴 (feat. Dynamo DB) (0) | 2024.01.17 |
ELB + EC2 Auto Scaling (2) | 2024.01.07 |
json 파일 업로드/다운로드하는 API 만들기 : AWS API Gateway, Lambda, S3 사용 (0) | 2023.12.24 |
AWS API Gateway로 S3에 파일 직접 업로드/다운로드하는 API 만들기 (0) | 2023.12.24 |