이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • Scale up과 scale out 중 무엇을 선택할지 어떤 지표로 판단하는가?
  • App instance를 늘리면 오히려 DB나 외부 API 장애가 커지는 경우는 언제인가?
  • 확장 선택은 성능, 장애 격리, 운영 복잡도 중 무엇을 바꾸는가?

개요

Scale up은 더 큰 장비로 한 노드의 한계를 올리는 선택이다. Scale out은 여러 노드로 부하를 나누는 선택이다. 둘 중 무엇이 좋은지는 기술 취향이 아니라 병목 위치가 결정한다. App CPU가 포화라면 app scale out이 직접 효과를 낼 수 있다. DB write lock이나 외부 API quota가 병목이라면 app을 늘리는 순간 더 많은 요청이 병목으로 몰린다.

이 문서가 바꾸는 설계 축

바뀌는 내용
성능병목 계층의 capacity를 올리거나 우회 경로를 만든다.
정합성write 병목을 queue나 shard로 나누면 중복, 순서, transaction 경계가 바뀐다.
장애 격리scale out은 일부 노드 장애를 흡수하지만 shared dependency 장애는 키울 수 있다.
운영 복잡도node 수, 배포, autoscaling, capacity review, 비용 추적이 늘어난다.

먼저 병목을 분류한다

관찰 지표병목 후보바로 scale out해도 되는가?
App CPU 85%, DB 여유app compute가능성이 높다.
App memory OOMapp memory 또는 leakscale up 전 leak과 object size 확인
DB CPU 90%, app 여유DB query/readapp 증설은 위험할 수 있다.
lock wait 증가DB write/hot rowapp 증설보다 transaction 분리
pool pending 증가DB connection 또는 slow querypool만 키우면 악화 가능
external quota 95%외부 APIapp 증설 효과 낮음
network egress 포화payload/CDN응답 크기와 CDN 검토
이 표 없이 “트래픽이 늘었으니 서버를 늘린다”고 하면 병목을 더 세게 두드릴 수 있다.

대표 시나리오

주문 목록 API와 주문 생성 API가 같이 느려졌다고 하자.

지표
App CPU45%
Hikari pending120
DB CPU82%
lock wait증가
read QPS8,000
write TPS700
외부 결제 API quota60%
이 상황에서 app instance를 2배로 늘리면 DB connection 요청도 늘어난다.
사용자 요청은 더 많이 DB로 들어가고 lock wait는 더 길어질 수 있다.
먼저 읽기와 쓰기를 나누고, 주문 목록은 cache/replica/query 개선, 주문 생성은 hot row와 transaction을 본다.

Scale up이 적합한 경우

Scale up은 구조 변경을 작게 유지한다. 다음 상황에서는 현실적인 선택이다.

  • 단일 노드 CPU나 memory만 부족하고 구조적 병목이 아직 작다.
  • 운영팀이 multi-node 운영 준비가 되어 있지 않다.
  • 단기간 이벤트를 넘겨야 하고 구조 변경 위험이 더 크다.
  • DB instance class 상향으로 read/write 여유가 충분히 생긴다. 하지만 상한이 있다. 큰 장비는 비용이 비선형적으로 늘고, 장애 시 영향 범위가 계속 하나의 큰 노드에 집중된다.

Scale out이 적합한 경우

Scale out은 stateless 작업에 잘 맞는다. 예를 들어 이미지 리사이즈, JSON serialization, API aggregation처럼 app CPU가 병목이면 효과가 크다.

single_instance_capacity = 500 QPS
target_peak_qps = 3,000
headroom = 1.5
required_instances = 3,000 * 1.5 / 500 = 9

이 계산은 app만 본 값이다. DB, Redis, external API capacity가 9개 instance의 부하를 받아야 한다. scale out 계산에는 downstream budget이 반드시 붙어야 한다.

Downstream budget

App을 늘릴 때 shared dependency 총량을 계산한다.

app_instances = 20
max_db_pool_per_instance = 20
max_possible_connections = 400
db_safe_connections = 250

이 경우 pool size를 줄이거나 app instance 상한을 낮춰야 한다. 더 많은 app은 더 많은 동시 DB 요청을 만들 수 있다. Redis, Kafka, 결제 API, 검색 cluster도 같은 방식으로 budget을 둔다.

선택을 단계화한다

확장은 보통 한 번에 sharding으로 가지 않는다.

단계선택판단
1Query/cache/rate limit구조 변경 없이 부하를 낮춘다.
2Scale up빠른 완화와 낮은 구조 변경
3App scale outstateless compute 병목 분산
4Read replica/read modelread 부하 분산
5Partitioning큰 테이블 관리와 query 범위 축소
6Shardingwrite/storage 한계를 여러 DB로 분산
앞 단계를 생략할 수도 있지만, 생략 이유가 숫자로 설명되어야 한다.

Spring 설정 예시

App scale out 때는 pool과 thread를 함께 조정한다.

server:
  tomcat:
    threads:
      max: 160
spring:
  datasource:
    hikari:
      maximum-pool-size: 12
      connection-timeout: 500

Pod 수를 늘릴수록 maximum-pool-size 총합이 커진다. scale out은 app 설정이 아니라 전체 시스템 설정이다.

장애 중 판단

장애 중에는 scale out이 안전한지 먼저 묻는다.

상황scale out 판단
App CPU 포화, DB 여유임시 scale out 가능
DB lock wait 증가scale out 보류, 유입 제한 우선
외부 API timeout 증가scale out 보류, circuit/rate limit 우선
queue consumer lag 증가downstream 여유가 있으면 consumer scale out
Redis memory/eviction 증가app scale out보다 cache policy 확인

개인 프로젝트 기준

  • 느린 API가 app 병목인지 DB 병목인지 최소한 로그와 지표로 구분한다.
  • scale up을 선택했다면 다음 전환 조건을 적는다.
  • scale out을 선택했다면 session, file, local cache, scheduler 상태를 확인한다.
  • DB pool 총합을 계산한다.
  • 포트폴리오에서는 “서버 증설”보다 병목 지표와 선택 이유를 말한다.

기업 운영 기준

  • capacity review는 app, DB, cache, queue, external API를 함께 본다.
  • autoscaling 정책은 CPU뿐 아니라 latency, queue age, pool pending을 검토한다.
  • scale up/down 작업에는 rollback과 비용 영향을 남긴다.
  • scale out 상한은 downstream budget과 함께 정한다.
  • 장애 중 scale out 허용 조건과 금지 조건을 runbook에 둔다.

위험 신호

  • DB lock wait가 높은데 app instance를 먼저 늘린다.
  • pool size를 키우면서 DB max connection 예산을 보지 않는다.
  • CPU만 보고 memory, I/O, lock, quota를 무시한다.
  • scale up을 임시 완화로 했지만 다음 전환 조건이 없다.
  • autoscaling이 있으니 capacity planning이 필요 없다고 말한다.
  • 성능 개선 후 비용과 장애 영향 범위를 다시 계산하지 않는다.

확인 질문

확인 질문

  • 확인 질문: Scale up과 scale out 판단의 첫 질문은 무엇인가?
    • 답변: 병목이 어느 계층의 어떤 지표에서 포화되는지 확인하는 것이다.
  • 확인 질문: App scale out이 DB 장애를 키우는 이유는 무엇인가?
    • 답변: app instance가 늘면 DB connection과 query 동시성도 늘어 기존 DB 병목을 더 압박할 수 있기 때문이다.
  • 확인 질문: Scale up이 나쁜 선택인가?
    • 답변: 아니다. 빠른 완화와 낮은 구조 변경이 장점이지만 상한, 비용, 단일 장애 영향 범위를 함께 봐야 한다.