01. 사용자 수에 따른 규모 확장성
단일 서버
사용자 요청 처리 과정
- 사용자는 도메인 이름을 이용하여 웹사이트에 접속
- DNS 에 도메인 이름을 질의하여 IP 주소로 변환하는 과정 필요
- DNS 조회 결과로 반환된 IP 주소로 HTTP 요청 전달
- 요청을 받은 웹 서버는 HTML 페이지나 JSON 형태의 응답을 반환
실제 요청이 오는 단말
- 웹 애플리케이션
- 모바일 앱
데이터베이스
데이터베이스의 종류
- 관계형 데이터베이스 RDBMS
- 자료를 테이블과 열, 칼럼으로 표현
- SQL 을 사용하여 여러 테이블에 있는 데이터를 그 관계에 따라 조인 가능
- 비-관계형 데이터베이스 NoSQL
- 키-값 저장소 / 그래프 저장소 / 칼럼 저장소 / 문서 저장소
- 일반적으로 조인 연산은 지원하지 않는다
- 적합한 경우
- 아주 낮은 응답 지연시간 필요한 경우
- 비정형 데이터를 다루는 경우
- 데이터(JSON, YAML 등)를 직렬화하거나 역직렬화 할 수 있기만 하면 되는 경우
- 아주 많은 양의 데이터를 저장할 필요가 있는 경우
데이터베이스 유형 비교
| 구분 | 데이터 모델 | 강점 | 적합한 경우 |
|---|---|---|---|
| RDBMS | 테이블/관계 | 강한 일관성, 조인 | 정형 데이터, 복잡한 쿼리 |
| NoSQL | 키-값/문서/그래프/칼럼 | 유연한 스키마, 수평 확장 | 비정형 데이터, 대규모 트래픽 |
수직적 규모 확장 vs 수평적 규모 확장
- 수직적 규모 확장 (Scale up)
- 서버에 고사양 자원을 추가하는 행위
- 서버로 유입되는 트래픽의 양이 적은 경우 유용하며 단순하게 적용 가능
- 단점
- 한계가 명확하다
- 장애에 대한 자동복구 및 다중화 방안의 부족
- 수평적 규모 확장 (Scale out)
- 더 많은 서버를 추가하여 성능을 개선하는 행위
규모 확장 방식 요약
| 구분 | 방법 | 장점 | 단점 |
|---|---|---|---|
| Scale up | 서버 사양 증설 | 적용이 간단 | 한계 명확, SPOF 위험 |
| Scale out | 서버 수평 확장 | 탄력적 확장 | 운영 복잡도 증가 |
사용자 급증 시 대응
- 부하 분산기 또는 로드 밸런서 도입
- 트래픽을 웹 서버에 고르게 분산
- 웹 서버는 사설 IP 로 통신하며 외부 요청은 로드 밸런서가 수신
- 대표적인 분산 알고리즘
- 라운드 로빈: 요청을 순서대로 분산한다
- 가중 라운드 로빈: 서버 성능에 비례해 가중치를 둔다
- 최소 연결: 활성 연결 수가 가장 적은 서버로 보낸다
- IP 해시: 클라이언트 IP 를 기준으로 같은 서버로 보낸다
- 선택 기준
- 서버 성능이 균등하면 라운드 로빈
- 서버 성능 차이가 크면 가중 라운드 로빈
- 연결 유지 시간이 길면 최소 연결
- 세션 고정이 필요하면 IP 해시
로드 밸런서 분산 알고리즘 요약
| 알고리즘 | 핵심 아이디어 | 적합한 상황 | 주의점 |
|---|---|---|---|
| 라운드 로빈 | 순서대로 분산 | 서버 성능이 균등 | 실시간 부하 반영이 약함 |
| 가중 라운드 로빈 | 성능에 비례해 분산 | 서버 성능 차이가 큼 | 가중치 튜닝 필요 |
| 최소 연결 | 활성 연결 수가 적은 서버로 분산 | 세션이 오래 유지됨 | 연결 수 집계 정확도 필요 |
| IP 해시 | 클라이언트 IP 기반 고정 | 세션 고정 필요 | 특정 IP 편중 가능 |
- 데이터베이스 다중화
- 주로 master-slave 관계를 설정하고 데이터 원본은 주 서버에, 사본은 부 서버에 저장하는 방식
- 장점
- 더 나은 성능: 병렬로 처리될 수 있는 쿼리 수가 늘어난다
- 안정성
- 가용성
캐시
값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소
캐시 전략
- Read-Through : 캐시가 없는 경우 DB 조회 후 캐시에 저장
- Write-Through : 쓰기 시 DB 와 캐시에 동시 반영
- Write-Behind : 캐시에만 쓰고 나중에 DB 에 비동기 저장
- Cache-Aside : 애플리케이션이 캐시/DB 직접 관리
캐시 전략 요약
| 전략 | 동작 방식 | 장점 | 단점 |
|---|---|---|---|
| Read-Through | 캐시 미스 시 DB 조회 후 저장 | 애플리케이션 단순화 | 캐시 의존도 증가 |
| Write-Through | 쓰기 시 캐시/DB 동시 반영 | 일관성 유지 용이 | 쓰기 지연 증가 |
| Write-Behind | 캐시에 쓰고 비동기 반영 | 쓰기 성능 우수 | 장애 시 유실 위험 |
| Cache-Aside | 앱이 캐시/DB 직접 제어 | 유연한 제어 | 구현 복잡도 상승 |
캐시 무효화 전략
- Manual Invalidate : 데이터 변경 시 캐시 삭제
- TTL : 자동 만료
- Versioning : 키에 버전을 붙여서 업데이트
- LRU / LFU : 오래되거나 자주 쓰이지 않는 항목 자동 제거
캐시 무효화 전략 요약
| 전략 | 핵심 아이디어 | 장점 | 주의점 |
|---|---|---|---|
| Manual Invalidate | 변경 시 직접 삭제 | 정확한 제어 | 구현/운영 부담 |
| TTL | 자동 만료 | 운영 단순 | TTL 동안 구버전 노출 |
| Versioning | 키에 버전 부여 | 즉시 반영 용이 | 키 관리 필요 |
| LRU/LFU | 자동 교체 | 메모리 효율 | 워크로드 편향 영향 |
캐시 교체 알고리즘
- FIFO
- MRU (Most Recently Used)
- Random Replacement
- ARC (Adaptive Replacement Cache)
- LRU + LFU 를 적절히 섞어 학습 기반으로 조절
- Clock (Second-Chance Algorithm)
- LRU 를 순환 버퍼 방식으로 간략화한 알고리즘
- Segregated LRU
- 캐시를 2단계로 나눔
- Probation : 새로운 항목
- Protected : 자주 사용되는 항목
- 캐시를 2단계로 나눔
유의 사항
- 사용되는 상황
- 데이터 갱신은 자주 일어나지 않지만 참조는 빈번하게 일어날 경우
- 캐시에 저장할 데이터
- 데이터를 휘발성 메모리에 두므로, 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않다
- 만료 정책 필요
- 일관성 유지
- 장애 대처
- 캐시 서버를 한 대만 두는 경우 해당 서버가 SPOF 가 될 가능성이 있다
- 캐시 메모리 크기 설정
CDN
정적 콘텐츠를 전송하는 데 쓰이는, 지리적으로 분산된 서버의 네트워크
고려 사항
- 비용
- 적절한 만료 시한 설정
- CDN 장애에 대한 대처 방안
- 콘텐츠 무효화 방법
동적 콘텐츠 캐싱
- Request Path, Query String, Cookie, Request Header 등의 정보에 기반하여 HTML 페이지를 캐싱
CDN 무효화 전략
- 버전드 URL: 파일명에 해시나 버전을 넣어 즉시 반영되도록 한다
- 퍼지 요청: 변경된 경로를 지정해 캐시를 삭제한다
- TTL 조정: 자주 바뀌는 자산은 짧게, 안정적인 자산은 길게 설정한다
- 소프트 퍼지: 기존 캐시를 유지하되 백그라운드에서 갱신한다
CDN 무효화 전략 요약
| 전략 | 핵심 아이디어 | 장점 | 주의점 |
|---|---|---|---|
| 버전드 URL | 파일명에 해시/버전 포함 | 즉시 반영, 캐시 충돌 최소화 | 빌드 파이프라인 필요 |
| 퍼지 요청 | 경로 지정 캐시 삭제 | 원하는 범위만 정리 가능 | 빈번하면 비용 상승 |
| TTL 조정 | 변경 주기 반영 | 운영 간편 | TTL 동안 구버전 노출 |
| 소프트 퍼지 | 백그라운드 갱신 | 사용자 경험 안정적 | 완전 즉시 반영은 어려움 |
무상태 웹 계층
웹 계층을 수평적으로 확장하기 위해서는 상태 정보를 웹 계층에서 제거해야 한다
상태 정보 의존적인 아키텍처
- 같은 클라이언트로부터의 요청은 항상 같은 서버로 전송되어야 한다
- 대부분의 로드밸런서가 이를 지원하기 위해 고정 세션 기능을 제공하나, 단점이 존재한다
무상태 아키텍처
- 사용자의 HTTP 요청은 어떤 웹 서버로도 전달될 수 있다
- 상태 정보가 필요한 경우, 공유 저장소로부터 데이터를 가져온다
- 트래픽 양에 따라 Auto-Scaling 을 통해 규모 확장이 가능하다
데이터 센터
- 지리적 라우팅
- 가장 가까운 데이터 센터 사용
- geoDNS : 사용자의 위치에 따라 도메인 이름을 어떤 IP 주소로 변환할지 결정할 수 있도록 해 주는 DNS 서비스
- 장애 발생 시 장애가 없는 데이터 센터 사용
다중 데이터센터 아키텍처 설계
- 트래픽 우회
- 데이터 동기화
- 테스트와 배포
메시지 큐
메시지의 무손실을 보장하는, 비동기 통신을 지원하는 컴포넌트
메시지의 버퍼 역할을 하며, 비동기적으로 전송한다
- 서비스 또는 서버 간 결합이 느슨해진다 → 규모 확장성에 용이
로그, 메트릭 그리고 자동화
로그
- 시스템의 오류와 문제들을 보다 쉽게 찾을 수 있다
- 로그를 단일 서비스로 모아주는 도구 활용 시 편리하게 검색 및 조회 가능
메트릭
- 사업 현황에 관한 유용한 정보를 얻거나 시스템의 현재 상태를 손쉽게 파악할 수 있다
- 호스트 단위 메트릭 : CPU, 메모리, 디스크 I/O
- 종합 메트릭 : 데이터베이스 계층의 성능, 캐시 계층의 성능
- 핵심 비즈니스 메트릭 : 일별 능동 사용자, 수익, 재방문
자동화
- 시스템이 크고 복잡해진 경우 생산성을 높이기 위해 필요하다
- 빌드, 테스트, 배포 등
데이터베이스의 규모 확장
수직적 확장 (Scale up)
- 기존 서버에 더 많은, 또는 고성능의 자원을 증설하는 방법
- 단점
- 하드웨어에는 한계가 있으므로 무한 업그레이드는 불가능하다
- SPOF 위험성이 크다
- 비용이 많이 든다
수평적 확장 (Scale out)
- 샤딩 : 더 많은 서버를 추가함으로써 성능을 향상하는 방법
- 데이터를 고르게 분할 할 수 있는 샤딩 키를 정하는 것이 중요하다
- 고려사항
- 데이터의 재 샤딩 : 샤드 소진 → 샤드 키 계산 함수 변경 및 데이터 재배치 필요
- 유명인사 문제 : 특정 샤드에 질의가 집중되어 서버에 과부하가 걸리는 문제
- 조인과 비정규화 : 여러 샤드에 걸친 데이터를 조인하기가 힘들다
기본 설계 전략
- 웹 계층은 무상태 계층으로
- 모든 계층에 다중화 도입
- 가능한 한 많은 데이터를 캐싱할 것
- 캐싱 가능성이 있는 대상은 최대한 분석
- 여러 데이터 센터를 지원할 것
- 정적 콘텐츠는 CDN 을 통해 서비스할 것
- 데이터 계층은 샤딩을 통해 그 규모를 확장할 것
- 각 계층은 독립적 서비스로 분할할 것
- 시스템을 지속적으로 모니터링하고, 자동화 도구들을 활용할 것
이 글은 저작권자의 CC BY 4.0 라이센스를 따릅니다.