View
트래픽이 터진 후에 준비하면 이미 늦다. 그러나 현실에서는 대부분 터지고 나서야 허둥지둥 트래픽 폭주 대응에 들어간다. 대용량 트래픽 처리는 장비 스펙을 올린다고 해결되지 않는다. 스타트업에서 일하다 보면 "일단 서버를 2배로 키워봐"라는 말을 가장 많이 듣게 되는데, 이는 대부분 돈만 태우고 근본 해결이 되지 않는다.
각설하고, 이 글은 DAU 1만짜리 서비스가 갑자기 1000만을 찍어도 죽지 않는 구조를 어떻게 미리 설계하느냐를 정리한 것이다. 측정·수평 확장·캐시 레이어·비동기 처리·비용, 이렇게 다섯 축으로 끊어서 보면 된다. 대기업 기술 블로그들이 자랑하는 성공담이 아니라, 중소·스타트업에서 실제로 쓸 수 있는 대용량 트래픽 처리 체크리스트 중심으로 간다.
스케일 이전에 측정부터 수행해야 하는 이유
병목을 모르면 스케일 아웃을 해도 소용이 없다
트래픽이 터졌을 때 사람들이 가장 먼저 하는 행동이 서버 인스턴스를 늘리는 것이다. 그러나 병목이 DB에 있으면 앱 서버를 10대로 늘려도 DB가 먼저 나가떨어진다. 오히려 커넥션 수만 더 늘어나 더 빨리 죽는다. 병목 지점(Bottleneck) 측정 없이 수평 확장을 먼저 하는 것은 돈만 태우고 상황을 악화시킨다.
측정이 먼저다. 어디가 느린지 모르면 무엇을 고쳐야 할지도 모른다. 이것이 대용량 트래픽 처리의 가장 첫 번째 원칙이다.
APM과 분산 추적으로 봐야 하는 지표 5개
대용량 트래픽 처리 시 최소한 확인해야 하는 지표는 다음 다섯 개다.
| 지표 | 허용치 | 넘어가면 위험 |
| p99 응답지연 | 500ms 이하 | 1초 넘어가면 이탈률 급증 |
| 에러율 | 0.1% 이하 | 1% 넘으면 장애 상황 |
| 초당 요청수(RPS) | 서버당 1000 내외 | 지속적으로 넘으면 스케일 필요 |
| DB 커넥션 사용률 | 70% 이하 | 90% 넘으면 풀 고갈 직전 |
| GC 타임 (JVM) | 전체 5% 이하 | 10% 넘으면 힙 튜닝 필요 |
p50, p95가 아닌 p99를 보는 이유는 장애는 꼬리 쪽에서 터지기 때문이다. 평균 응답이 200ms여도 p99가 3초라면 고객 1%는 지옥을 경험 중인 것이다. 그리고 이 1%가 소셜에 올려 바이럴을 일으킨다.
관측성 도구의 현실적인 선택
Datadog이 좋다는 것은 다 알지만 스타트업이 쓰기에는 월 과금이 무겁다. DAU 10만 급이면 월 200~500만 원이 쉽게 나간다. 비용을 절약하려면 Grafana + Prometheus + Loki 조합이 현실적이다. 셋업은 다소 귀찮지만 요금은 인프라 비용만 들어간다.
국내 상황이라면 네이버가 만든 Pinpoint도 괜찮다. 자바 기반이면 에이전트 하나를 붙여 트랜잭션 전체 경로를 볼 수 있다. 다만 Node.js나 Go는 에이전트 지원이 약해 이럴 땐 Grafana 스택으로 간다.
스케일 아웃과 스케일 업을 섞어 대용량 트래픽 처리 구조를 짜는 법
스케일 아웃 vs 스케일 업, 어떤 상황에서 무엇을 쓰는가
스케일 업은 서버 스펙을 올리는 것이다 (예: t3.medium → m5.xlarge). 스케일 아웃은 같은 스펙의 서버를 여러 대 붙이는 것이다.
스케일 업이 유리한 경우
- DB처럼 상태(State)가 있는 서비스
- 로직이 CPU·메모리 집약적인 경우
- 인스턴스 1대 비용이 10대 비용보다 저렴한 경우
스케일 아웃이 유리한 경우
- 상태가 없는 API 서버
- 트래픽이 시간대별로 크게 변동하는 경우
- 장애 격리가 중요한 경우 (1대가 죽어도 9대는 살아있음)
대용량 트래픽 처리의 기본 원칙은 "앱 서버는 스케일 아웃, DB는 최대한 스케일 업 후 Read Replica" 이다. 이것이 정답이다.
무상태 서비스로 만들어야 오토스케일링이 먹힌다
세션을 서버 메모리에 들고 있으면 서버를 끄는 순간 로그인이 모두 풀린다. 오토스케일링이 서버를 죽이는 것은 정상 동작이지만, 이때 사용자가 튕기면 서비스 장애가 된다. 세션은 Redis로 빼고 JWT 토큰을 쓰는 식으로 서버를 무상태(Stateless)로 만들어야 한다.
파일 업로드도 마찬가지다. 로컬 디스크에 저장하면 안 된다. S3나 오브젝트 스토리지로 빼야 오토스케일링이 의미가 있다.
로드밸런서·Nginx·ALB 선택 기준
AWS를 쓴다면 ALB(Application Load Balancer)가 기본 정답이다. L7에서 동작하여 경로별 라우팅이 된다. 월 20~30달러에 트래픽당 과금이 붙는다.
Nginx를 프론트에 둘지 ALB 하나로 끝낼지는 요구사항에 따라 다르다. Nginx를 쓰면 worker_connections 튜닝으로 단일 인스턴스당 10만 커넥션도 받을 수 있다. 기본값 1024는 트래픽이 터지면 바로 거덜난다. keepalive_timeout, proxy_buffering 같은 디테일도 함께 건드려야 한다.
DB가 먼저 죽는다, 캐시 레이어 설계가 핵심이다

출처: javatechonline.com
캐시 적중률 90%를 넘기면 DB 부하가 1/10로 떨어진다
대용량 트래픽 처리에서 가장 먼저 죽는 것은 DB다. 앱 서버는 스케일 아웃으로 간단히 늘리지만, DB는 그것이 어렵다. 그래서 캐시 레이어로 DB 앞을 막는 것이 핵심이다.
캐시 적중률(Hit Rate) 90%라면 DB에 오는 쿼리가 원래의 10%로 줄어든다. 95%를 찍으면 5%로 줄어든다. 이것이 DB 1/10배 스펙으로 같은 트래픽을 받는 비결이다. 초당 1만 쿼리를 받던 DB가 캐시 95% 적중률이라면 초당 500 쿼리만 받는다. 대역폭·비용·복잡도가 전부 10분의 1이 된다.
Redis 싱글 vs 클러스터, 어느 시점에 갈아타는가
Redis는 싱글 인스턴스로도 초당 10만 RPS를 받아낸다. DAU 10만 급에서는 싱글로 충분하다. ElastiCache Redis r6g.large 한 대에 월 15만 원 정도가 나간다.
메모리가 32GB를 넘어가기 시작하면 클러스터를 고려한다. 데이터가 한 노드에 전부 들어가지 못하면 샤딩이 필요한 것이다. 다만 클러스터는 운영 복잡도가 확 오르기 때문에 정말 필요해질 때까지 싱글로 버티는 것이 맞다. 쓸데없이 일찍 클러스터를 도입했다가 후회하는 사람이 많다.
캐시 무효화 전략
캐시 무효화(Cache Invalidation)는 컴퓨터 공학의 2대 난제 중 하나라는 말이 있을 정도로 골치 아프다. 현실적으로 쓰이는 패턴은 세 가지다.
- TTL 방식: 가장 간단하다. 60초·5분·1시간 같은 식으로 만료시간을 박아두고 DB에서 다시 가져온다. 정확도는 떨어지지만 운영이 편하다
- Write-through: DB에 쓸 때 캐시에도 함께 쓴다. 일관성은 높지만 쓰기 성능이 다소 깎인다
- Cache-aside (Lazy loading): 캐시 miss가 나면 DB에서 읽어 캐시에 넣는다. 가장 많이 쓰이는 패턴이다
TTL을 무한으로 놓고 잊어버리는 것이 안티패턴이다. 캐시를 먹는 것을 까먹으면 stale 데이터가 몇 주씩 남는다.
Read Replica를 붙이는 시점과 지연 복제 이슈
읽기 쿼리가 쓰기보다 10배 많으면 Read Replica(읽기 레플리카)를 붙일 시점이다. RDS 기준 단일 클릭으로 만들 수 있다. 애플리케이션 레벨에서 쓰기는 Master, 읽기는 Replica로 라우팅하면 된다.
다만 복제 지연(Replication Lag)을 염두에 두어야 한다. 방금 쓴 데이터를 바로 Replica에서 읽으면 나오지 않을 수 있다. 주문 직후 내 주문 목록 조회 같은 시나리오는 Master에서 읽어야 한다. 사용자 경험을 기준으로 "내가 방금 한 행동"은 Master, "남의 데이터" 조회는 Replica로 가는 것이 기본 룰이다.
동기 처리를 전부 걷어내고 비동기로 넘기는 포인트

출처: blog.bytebytego.com
Kafka·RabbitMQ로 급한 것만 동기 처리한다
회원가입 시 환영 메일 발송, 결제 후 알림 푸시, 주문 후 통계 집계 같은 작업을 전부 동기로 처리하면 응답시간이 늘어난다. 사용자는 메일 발송이 완료될 때까지 기다리는 것이 아니다. 그저 "회원가입 완료" 화면만 빨리 뜨면 된다.
Kafka나 RabbitMQ 같은 메시지 큐를 앞에 두고, 동기 처리할 것은 API 응답에 필요한 것만 남긴 채 나머지는 전부 큐로 던져버린다. 이렇게 하면 API 응답시간이 50~80% 줄기도 한다. 사용자 체감은 확 빨라지고 서버 부하 분산도 함께 이루어진다.
Kafka는 초당 100만 메시지 처리가 가능한 괴물이다. 다만 운영 복잡도가 높다. 스타트업이라면 SQS(AWS)나 RabbitMQ 같은 간단한 큐로 시작하여 성장에 따라 갈아타는 편이 낫다. 처음부터 Kafka를 들이대면 운영 리소스가 감당되지 않는다.
서킷 브레이커·백프레셔로 장애 전파를 차단한다
MSA에서 한 서비스가 느려지면 그것을 호출하는 모든 서비스가 함께 느려진다. 커넥션 풀이 꽉 차 연쇄적으로 전부 죽는다. 이것이 장애 전파다. 서킷 브레이커(Circuit Breaker)는 일정 에러율을 넘으면 해당 서비스 호출을 일시 차단한다. 차단되는 동안 빠른 실패로 응답하여 전체 장애로 번지는 것을 막는다.
Resilience4j, Hystrix 같은 라이브러리가 있으며, 이스티오 같은 서비스 메시를 쓰면 인프라 레벨에서 붙일 수도 있다. 트래픽 1000배를 가정하면 필수다.
백프레셔(Backpressure)는 소비자가 감당하지 못할 만큼 빨리 들어오는 요청을 의도적으로 느리게 받는 패턴이다. 큐 길이가 일정 수준을 넘으면 429 에러를 주거나 대기시간을 부여하는 식이다.
서버리스(Lambda)로 스파이크를 흡수하는 패턴
갑작스러운 트래픽 스파이크를 EC2만으로 받으면 스케일링 몇 분 동안 당연히 터진다. AWS Lambda는 이론상 초당 수만 개의 동시 실행이 가능하다. 비동기 처리 일부를 Lambda로 빼놓으면 스파이크 흡수용 버퍼가 된다.
이미지 리사이징, 알림 발송, 로그 처리 같은 작업은 Lambda가 제격이다. 다만 DB 커넥션 관리가 까다로우므로 RDS Proxy를 함께 써야 한다.
단계별 임계치 체크리스트 (DAU별)
DAU 구간별로 필요한 대용량 트래픽 처리 수준이 다르다. 무엇을 언제 해야 하는지 정리하면 다음과 같다.
| DAU 구간 | 필요 구성 | 월 인프라 비용 추정 |
| 1만 미만 | 모놀리식 + RDS 단일 + S3 | 20~50만원 |
| 1만~10만 | 캐시(Redis 싱글) + Read Replica + CDN | 80~200만원 |
| 10만~100만 | 메시지큐 + 오토스케일링 + DB 샤딩 검토 | 500~1500만원 |
| 100만 이상 | 마이크로서비스 + 글로벌 리전 + 엣지 컴퓨팅 | 3000만원 이상 |
DAU 1만 미만 구간
모놀리식 앱 서버 1~2대와 RDS 단일 인스턴스로 충분하다. 캐시도 필요 없다. 이 구간에서 쿠버네티스를 도입하거나 마이크로서비스로 쪼개는 것은 시간 낭비이자 오버엔지니어링이다.
DAU 1만~10만 구간
Redis 캐시, Read Replica, CDN 세 가지가 기본이다. CDN을 도입하면 정적 리소스 트래픽이 서버에서 전부 빠지고 CloudFront·Cloudflare가 처리한다. 이 단계에서 이미 서버 부하의 60% 이상이 줄어든다.
DAU 10만~100만 구간
메시지 큐로 비동기 처리, 오토스케일링 적용, 필요하다면 DB 샤딩을 검토한다. 여기서부터는 관측성(APM)이 없으면 운영이 불가능하다. 장애 원인을 찾는 데 하루가 걸린다.
DAU 100만 이상 구간
마이크로서비스 분리, 멀티 리전 배포, 엣지 컴퓨팅까지 들어간다. 이 단계는 전담 SRE(Site Reliability Engineer) 팀이 필요하다. 개발자 몇 명으로는 불가능하다.
확장하면 비용은 얼마나 더 나가는가

출처: www.techradar.com
AWS 기준 월 요금 실측 비교
중소 서비스 기준 실제로 나가는 비용을 비교하면 다음과 같다. 서울 리전 기준 2025년 말 가격이다.
| 구성 | 월 비용 | 처리 가능 DAU |
| t3.medium 3대 + RDS t3.small 단일 | 약 35만원 | 1만 |
| m5.large 4대 + RDS m5.large Multi-AZ + ElastiCache r6g.large | 약 230만원 | 10만 |
| m5.xlarge 8대(ASG) + Aurora Multi-AZ + Redis 클러스터 + ALB + CloudFront | 약 850만원 | 100만 |
대용량 트래픽 처리 단계로 올라갈 때마다 비용은 2~4배씩 뛰지만, 처리 가능한 트래픽은 10배씩 늘어난다. 제대로 설계하면 단위 비용 효율이 좋아진다.
CDN을 쓰면 아웃바운드 트래픽 비용이 얼마나 절감되는가
AWS EC2 아웃바운드는 GB당 126원이다. CloudFront는 GB당 100원으로 약간 저렴하며, 캐싱 덕에 오리진(서버) 트래픽이 확 줄어든다. 이미지·CSS·JS 같은 정적 리소스를 CDN에 올리면 실질 비용이 40~60% 절감된다. DAU 10만 서비스에서 월 100만 원씩 아껴지는 경우도 있다.
Reserved Instance·Savings Plan은 언제 사야 이득인가
온디맨드로 6개월 이상 쓸 인스턴스는 무조건 Savings Plan을 산다. 1년 약정에 30~40% 할인, 3년에 50~60% 할인이다. 단, 트래픽 예측이 서지 않으면 섣불리 장기 약정을 걸어서는 안 된다. DAU 변동이 큰 초기에는 온디맨드로 가다가 안정화되면 전환하는 것이 맞다.
대용량 트래픽 처리 시 피해야 할 안티패턴 모음
측정 없이 스케일 아웃을 먼저 한다
반복하지만 이것이 1등 안티패턴이다. 병목을 모르고 서버만 늘리면 돈만 태우고 풀리지 않는다. 항상 측정이 먼저다.
캐시를 걸어놓고 TTL을 무한으로 둔다
TTL 없는 캐시는 영영 stale 데이터를 반환한다. 상품 가격이 바뀌었는데 캐시는 옛 가격이다. 이렇게 되면 CS가 폭주한다. 짧은 TTL + 명시적 무효화가 기본 원칙이다.
DB 샤딩을 너무 일찍 한다
샤딩은 운영 복잡도가 확 올라간다. 조인을 못 하고, 트랜잭션이 깨지고, 재분배 지옥이 펼쳐진다. DAU 100만이 되지 않는다면 수직 스케일업 + Read Replica로 버티는 편이 낫다. 대용량 트래픽 처리 능력이 정말 필요해질 때 도입해야 한다.
서비스 분리도 하지 않은 채 몰래 쿠버네티스부터 도입한다
모놀리식인데 쿠버네티스를 붙이면 이득보다 손해가 크다. 단일 바이너리 하나를 띄우는데 마스터 노드 3대를 돌리면 오버헤드다. MSA로 쪼갤 서비스가 없다면 ECS나 그냥 EC2로도 충분하다.
대용량 트래픽 처리는 기술 싸움이 아니라 순서 싸움이다
정리하면 순서는 이렇다. 첫째, 측정이 먼저다. APM을 붙이고 p99 응답시간·에러율·DB 커넥션부터 본다. 둘째, 캐시로 DB 앞을 막는다. 적중률 90%를 넘기는 것이 목표다. 셋째, 동기 처리를 걷어내 메시지 큐로 넘긴다. 넷째, 이 모든 것을 한 뒤에 수평 확장에 들어간다.
트래픽 1000배는 기술 싸움이 아니라 순서 싸움이다. 순서가 맞지 않으면 장비를 10배 더 써도 풀리지 않고, 순서가 맞으면 인프라 2~3배로도 버틴다.
오늘 당장 할 일은 간단하다. 서비스에 APM이 아직 붙지 않았다면 Grafana+Prometheus라도 붙여 p99 응답시간을 재는 것부터 시작하면 된다. 측정을 시작하면 이미 절반은 온 것이다. 그다음은 Redis 캐시 레이어 설계 가이드와 CDN 도입 후기 글을 찾아 읽어보면 단계적으로 대용량 트래픽 처리 역량이 쌓인다. 지금 터지지 않는 서버가 6개월 뒤에도 터지지 않는다는 보장은 없다. 미리미리 대비하는 것이 최선이다.
'DevOps' 카테고리의 다른 글
| 도커를 만든 사람을 알면 더 흥미롭다, 솔로몬 하익스 이야기 (0) | 2026.04.30 |
|---|---|
| CGI, WSGI, WAS의 차이 정리 — 웹서버 공부할 때 헷갈리는 개념 한 번에 끝내기 (0) | 2026.04.25 |
| 쿠버네티스(Kubernetes)는 누가 만들었는가? 개발자 3인방과 탄생 배경을 파헤치다 (1) | 2026.04.24 |
| CPU 아키텍처에 따른 Docker Multi Architecture 빌드 구성하기 (0) | 2024.02.22 |
| Prometheus (프로메테우스) 대해 알아보고 설치해보자 (0) | 2024.01.31 |
