이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.
공부 › 네트워크 › 웹 서버 앞의 장비
로드밸런서와 스케일 아웃
서버를 늘리면 어디까지 버티나
서버를 더 크게 바꾸는 대신 서버 수를 늘려 부하를 나누는 것이 스케일 아웃입니다. 로드밸런서가 요청을 여러 서버에 나눠 주고, 서버는 요청마다 DB를 한 번씩 씁니다. 서버를 늘려 갈 때 처리량이 어디까지 늘고 어디가 먼저 막히는지 봅니다.
개념 모형 · 관계를 보이는 예시 수치
이 실습에 나오는 개념
- 스케일 업과 스케일 아웃
- 스케일 업은 서버 한 대의 사양(CPU, 메모리)을 높여 처리 능력을 키우는 것이고, 스케일 아웃은 서버의 수를 늘려 부하를 나누는 것이다. 스케일 업은 간단하지만 한계와 비용 문제가 있고, 스케일 아웃은 유연하게 확장할 수 있지만 서버가 상태를 갖지 않도록 설계하고 요청을 분산할 장치가 필요하다.
- 로드밸런서
- 들어오는 요청을 여러 서버에 나눠 보내는 장치다. 서버의 상태를 주기적으로 확인(헬스 체크)해 문제가 있는 서버로는 요청을 보내지 않는다. 한 서버에 부하가 몰리는 것을 막고, 일부 서버에 장애가 나도 서비스를 유지하게 한다.
- 병목(Bottleneck)
- 시스템 전체의 처리 성능을 제한하는 가장 느린 부분이다. 다른 부분을 아무리 개선해도 병목이 그대로면 전체 성능은 나아지지 않는다. 성능 개선은 측정으로 병목을 찾는 것에서 시작한다.
- 오토스케일링
- CPU 사용률이나 요청 수 같은 지표에 따라 서버의 수를 자동으로 늘리거나 줄이는 기능이다. 부하가 많을 때는 서버를 추가하고 적을 때는 줄여 비용을 아낀다. 서버가 추가되어 요청을 받을 수 있게 되기까지 시간이 걸리므로, 예고된 급증에는 미리 늘려 두는 것이 안전하다.
- TPS와 응답 시간 백분위
- TPS는 시스템이 1초에 처리하는 요청(트랜잭션)의 수다. 응답 시간은 평균만 보면 일부 느린 요청이 가려지므로 백분위로 본다. p95가 1초라는 것은 요청의 95%가 1초 안에 처리된다는 뜻이고, p99는 99%를 기준으로 한 값이다. 느린 일부 요청이 사용자 경험을 좌우하므로 p95, p99를 함께 관리한다.
이렇게 바꿔 보세요
- 처음 설정으로 — 초당 1,000건에 서버 2대. 서버가 감당하지 못합니다.
- 서버를 3대로 (스케일 아웃) — 같은 사양의 서버를 한 대 더 붙입니다.
- 서버 사양을 두 배로 (스케일 업) — 대수는 그대로 2대, 한 대의 성능을 올립니다.
- 서버를 계속 늘리면 — 초당 3,000건에 서버 8대. 이번에는 DB가 막힙니다.
- 3대 중 1대 장애 — 남은 2대가 나눠 받습니다. 여유가 없으면 함께 넘칩니다.
- 서버가 1대뿐일 때 장애 — 받아 줄 서버가 없어 서비스 전체가 멈춥니다.
처음 설정으로 실행하면
- 초당 1000건의 요청이 로드밸런서에 도착합니다. 사용자는 서버가 몇 대인지 모르고 로드밸런서의 주소 하나만 압니다.
- 로드밸런서가 요청을 살아 있는 서버 2대에 고르게 나눕니다. 서버 한 대가 초당 500건을 받습니다. 한 대의 처리 능력은 초당 400건이므로 부하는 125%입니다. 처리 능력을 넘었습니다. 넘친 요청은 대기하다 시간 초과되거나 거절됩니다.
- 서버들이 처리한 초당 800건이 DB로 갑니다. DB의 처리 능력은 초당 2000건이므로 부하는 40%입니다.
- 결과: 초당 800건을 처리하고 200건은 처리하지 못했습니다. 병목은 애플리케이션 서버입니다.
실행 결과
- 초당 1000건 중 800건을 처리했습니다(200건 초과). 서버 한 대의 부하는 125%, DB 부하는 40%입니다.
- 서버가 병목입니다. 서버를 더 붙이거나(스케일 아웃) 사양을 올리면(스케일 업) 풀립니다. 스케일 아웃은 한 대가 죽어도 버티고 계속 늘릴 수 있지만, 서버가 로그인 상태 같은 것을 자기 메모리에 들고 있지 않아야 합니다. 스케일 업은 구조 변경이 없지만 한계에 빨리 닿고 비용도 가파르게 오릅니다.
코드
# 로드밸런서 설정 (nginx 예)
upstream app {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
server {
listen 80;
location / { proxy_pass http://app; } # 차례로 돌아가며 전달
}
# 서버 1대: 초당 400건 처리
# DB: 초당 2000건 처리 (요청 1건에 쿼리 1번)
이 모형의 전제
모든 요청의 무게가 같고, 요청 1건이 DB 쿼리 1번을 쓴다고 단순화했습니다. 로드밸런서는 요청을 고르게 나누며 자체 한계는 없다고 가정했습니다(실제로는 로드밸런서도 이중화합니다). 처리 능력을 넘은 요청은 "처리 못 함"으로만 셌는데, 실제로는 한계에 가까워질수록 대기 시간이 먼저 급격히 늘어납니다. 숫자는 관계를 보이기 위한 예시이며 실측값이 아닙니다.
앞 실습: TLS 핸드셰이크 · 다음 실습: 프록시와 리버스 프록시