시스템 규모 확장 전략: 스케일 업부터 샤딩까지
한눈에 보기
트래픽 증가에 대응하는 시스템 확장 전략을 정리한다. 스케일 업과 스케일 아웃의 비교, 무상태 설계와 세션 처리, 로드 밸런싱, 캐시, 데이터베이스 복제와 샤딩까지 다룬다.
최종 업데이트 2026.09.17
시스템 규모 확장(Scaling)은 사용자와 트래픽이 늘어날 때 서비스가 성능과 안정성을 유지하도록 처리 용량을 키우는 설계 전략이다. 확장 방향은 서버 한 대의 사양을 높이는 스케일 업(Scale Up)과 서버 수를 늘리는 스케일 아웃(Scale Out)으로 나뉘며, 스케일 아웃을 제대로 하려면 무상태 설계, 로드 밸런싱, 캐시, 데이터베이스 분산까지 함께 고려해야 한다. 시스템 설계 면접의 거의 모든 문제가 이 확장 전략을 뼈대로 삼는다.
스케일 업과 스케일 아웃
스케일 업은 수직 확장(Vertical Scaling)이라고도 하며, 기존 서버의 CPU, 메모리, 디스크를 더 좋은 것으로 교체하는 방식이다. 애플리케이션 구조를 바꿀 필요가 없어 가장 간단하지만, 하드웨어 성능에는 물리적 상한이 있고 사양이 올라갈수록 비용이 비선형적으로 커진다. 무엇보다 서버가 한 대뿐이므로 그 서버가 죽으면 서비스 전체가 멈추는 단일 장애점(Single Point of Failure)이 된다.
스케일 아웃은 수평 확장(Horizontal Scaling)으로, 비슷한 사양의 서버를 여러 대 추가해 부하를 나눠 받는 방식이다. 이론상 서버를 계속 추가할 수 있어 확장 한계가 훨씬 높고, 일부 서버가 죽어도 나머지가 트래픽을 받아내므로 가용성(availability)이 좋아진다. 대신 여러 서버가 하나의 서비스처럼 동작해야 하므로 설계 복잡도가 올라간다.
| 구분 | 스케일 업 | 스케일 아웃 |
|---|---|---|
| 방법 | 서버 사양 향상 | 서버 대수 증가 |
| 확장 한계 | 하드웨어 상한 존재 | 이론상 거의 무제한 |
| 장애 내성 | 단일 장애점 | 일부 장애 시에도 서비스 유지 |
| 설계 난이도 | 낮음 | 무상태 설계, 분산 처리 필요 |
| 적합한 대상 | 관계형 데이터베이스, 초기 서비스 | 웹, API 서버, 대규모 트래픽 |
무상태 설계가 전제 조건인 이유
스케일 아웃이 성립하려면 어떤 서버가 요청을 받아도 같은 결과를 내야 한다. 이를 위해 서버는 요청 처리에 필요한 상태를 자기 메모리에 담아 두지 않는 무상태(Stateless) 구조여야 한다. 대표적인 문제가 로그인 세션이다. 세션을 서버 메모리에 저장하면 사용자가 다음 요청에서 다른 서버로 연결될 때 로그인이 풀려 버린다.
해결책은 세 가지가 있다. 로드 밸런서가 같은 사용자를 항상 같은 서버로 보내는 고정 세션(Sticky Session)은 구현이 쉽지만 부하가 고르게 분산되지 않고 서버 장애 시 세션이 사라진다. 세션 저장소를 레디스(Redis) 같은 외부 스토리지로 분리하면 모든 서버가 세션을 공유할 수 있어 가장 널리 쓰인다. 아예 서버에 상태를 두지 않는 JWT(JSON Web Token) 같은 토큰 방식은 토큰 자체에 인증 정보를 담아 검증만 하면 되므로 확장에 가장 유리하다.
로드 밸런싱과 자동 확장
서버가 여러 대가 되면 트래픽을 나눠 주는 로드 밸런서(Load Balancer)가 필요하다. 로드 밸런서는 라운드 로빈(Round Robin), 최소 연결(Least Connections) 같은 알고리즘으로 요청을 분배하고, 주기적인 헬스 체크(health check)로 비정상 서버를 분배 대상에서 자동 제외한다. 덕분에 서버 추가와 제거가 사용자 모르게 이루어진다.
여기에 오토 스케일링(Auto Scaling)을 결합하면 CPU 사용률이나 요청 수 같은 지표를 기준으로 서버 대수를 자동 조절할 수 있다. 트래픽이 몰리는 시간대에는 서버를 늘리고 새벽에는 줄여서 비용과 성능의 균형을 맞춘다. 이 자동화가 매끄럽게 동작하려면 앞서 말한 무상태 설계가 반드시 전제되어야 한다.
캐시로 부하 줄이기
확장은 용량을 키우는 것뿐 아니라 불필요한 작업을 줄이는 것으로도 달성된다. 캐시(Cache)는 자주 조회되는 데이터를 빠른 저장소에 복사해 두어 원본 데이터베이스까지 가는 요청을 줄이는 기법이다. 계층별로 브라우저 캐시, 정적 자원을 사용자 가까이에서 제공하는 CDN(Content Delivery Network), 애플리케이션과 데이터베이스 사이의 레디스 캐시가 있다.
가장 흔한 패턴은 캐시 어사이드(Cache Aside)다. 조회 시 캐시를 먼저 확인하고, 없으면 데이터베이스에서 읽어 캐시에 채운 뒤 반환한다. 캐시를 쓸 때는 원본과 캐시가 달라지는 정합성 문제를 만료 시간(TTL, Time To Live)과 갱신 시 무효화 전략으로 관리해야 하고, 만료가 한꺼번에 몰려 데이터베이스로 요청이 쏟아지는 캐시 스탬피드(Cache Stampede)도 주의해야 한다.
데이터베이스 확장: 복제와 샤딩
애플리케이션 서버를 아무리 늘려도 결국 병목은 데이터베이스로 모인다. 첫 번째 대응은 복제(Replication)다. 쓰기를 담당하는 주(Primary) 서버와 읽기를 담당하는 복제(Replica) 서버를 분리하면, 대부분의 서비스에서 비중이 큰 읽기 트래픽을 여러 복제본으로 분산할 수 있다. 다만 복제는 비동기로 이루어지는 경우가 많아 복제 지연(replication lag)으로 인해 방금 쓴 데이터가 읽기 서버에 아직 없을 수 있다는 점을 감안해야 한다.
쓰기 자체가 한계에 도달하면 샤딩(Sharding)으로 데이터를 수평 분할한다. 사용자 ID 같은 샤드 키(shard key)를 기준으로 데이터를 여러 데이터베이스에 나눠 저장하는 방식이다. 해시 기반 샤딩은 데이터를 고르게 분산시키지만 범위 조회가 어렵고, 범위 기반 샤딩은 그 반대다. 샤딩을 도입하면 여러 샤드에 걸친 조인과 트랜잭션이 어려워지고, 특정 키에 트래픽이 몰리는 핫스팟(hotspot) 문제와 샤드 재분배(resharding) 비용이 생기므로 복제와 캐시로 버틸 수 있을 때까지는 도입을 미루는 것이 정석이다.
면접에서 이렇게 물어본다
- 스케일 업과 스케일 아웃의 차이를 설명하고, 각각 어떤 상황에서 선택하겠는가.
- 서버를 여러 대로 늘렸을 때 세션 문제는 왜 생기고 어떻게 해결하는가.
- 캐시를 도입할 때 생기는 정합성 문제와 그 대응 전략을 설명해 보라.
- 데이터베이스 읽기 부하와 쓰기 부하는 각각 어떻게 분산하는가.
- 샤딩의 샤드 키는 어떤 기준으로 정해야 하며, 잘못 정하면 어떤 문제가 생기는가.
DevOps / 인프라에서 같이 읽기
- AWS에 스프링 부트를 배포하는 네 가지 방법EC2 수동 배포부터 배포 스크립트, CodeDeploy, 컨테이너까지 AWS에 스프링 부트를 배포하는 방식의 발전 단계를 정리한다. 각 방식의 원리와 무중단 배포 전략, 롤백까지 다룬다.
- CI의 개념과 CI 도구의 흐름: 깃허브 액션과 Travis CI짧은 주기로 병합하고 커밋마다 빌드와 테스트를 자동 실행하는 지속적 통합(CI)의 개념을 정리한다. 깃허브 액션 중심의 파이프라인 흐름과 Travis CI의 역사적 맥락, CD와의 차이를 다룬다.
이 개념, 내 코드에서는 어떻게 물어볼까요
데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.
공고 넣고 시작하기