Search

일평균 100만건의 스파이크 트래픽을 감당하는 RDS 설계

개요

기본적으로 채팅 데이터는 수집 대상에 따라 기하급수적으로 증감 할 수 있으므로 현재 서비스에서 제공하고자 하는 데이터는 일간 채팅 수집 건을 기준으로 일평균 100만건(단순 Insert 기준)이라고 가정한다.

전체 구조 요약

최종 결론 (요약 먼저 줌)

항목
추천 설정
RDS 엔진
Aurora PostgreSQL (v16.6)
인스턴스 유형
db.r6g.xlarge (메모리 최적화 + ARM 그라비톤)
확장 전략
Aurora Auto Scaling 리더 구성
스토리지 구성
Aurora I/O 최적화 (유동 트래픽 대응)
고가용성
Multi-AZ + 최소 1개 리더 노드
데이터 분산
작성자는 메인, 조회는 리더 분산 처리
테이블 설계
시간 파티셔닝 + 인덱싱 전략 강화
아카이빙 전략
1개월 지난 로그 → S3 + Athena
성능 모니터링
Performance Insights, Enhanced Monitoring 활성화

왜 이렇게 세팅해야 되는가?

1. 트래픽 유동성 (10만 ~ 100만건/일) = 피크 대비 구조 필요

초당 처리량 기준 약 1.2 ~ 11.5 TPS (단순 삽입 기준)
여기에 동시 쿼리 / 검색 / JOIN / 집계 들어오면, 성능 곱창.
→ 정답은 Aurora PostgreSQL + 수평 리더 확장 + I/O 최적화

2. 인스턴스: db.r6g.xlarge부터 시작

4vCPU, 32GiB RAM → 버스트 대응 충분
Graviton 계열로 비용 대비 성능 우수
100만 건 단일날 스파이크는 Aurora의 리더 리플리카 Auto Scaling으로 대응
(리더 수 증가로 조회 분산 처리)

3. 스토리지: Aurora I/O 최적화 = 필수

유동 트래픽은 I/O 예측 어려움 → 요청당 과금 비효율
I/O 포함형 스토리지는 IOPS가 급증할 때 비용 예측 안정성 + 성능 안정성 확보

4. 리더 노드 + 오토 스케일

읽기 분산은 기본
스파이크 발생 시 Aurora의 Auto Scaling Read Replica로 대응
ReaderEndpoint 로 라우팅하고 앱에서 쓰기/읽기 분리

5. 테이블 설계 / 인덱싱

chat_log 같은 경우:
CREATE TABLE chat_log ( id BIGSERIAL PRIMARY KEY, channel_id TEXT NOT NULL, user_id TEXT NOT NULL, message TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_channel_time ON chat_log (channel_id, created_at DESC);
Plain Text
복사
시간 파티셔닝 + 보조 인덱스로 스캔 최소화

6. 장기 데이터 아카이빙

1개월 지난 row → S3 (ETL 또는 Lambda로 주기적 dump)
Athena + Glue Table로 검색 가능
RDS 비용 절감 + 성능 유지

7. 비용 예상

r6g.xlarge + I/O 포함형 + Multi-AZ + 1 리더
월 800~1100 USD 예상 (100만 건 기준 피크 트래픽 포함)