가상 면접 사례로 배우는 대규모 시스템 설계 기초를 읽고 정리한 글입니다.
단일 서버
처음에는 단 한 대의 서버에서 실행되는 간단한 시스템부터 설계해 본다.
웹, 앱, 데이터베이스, 캐시 등이 전부 서버 한 대에서 실행되는 구조이다.
이 구조에서 사용자 요청 처리 흐름을 살펴보자
- 사용자는 api.mysite.com 같은 도메인 이름으로 접속한다.
접속을 위해 도메인 이름 서비스(DNS)를 통해 IP 주소로 변환해야 한다. DNS는 보통 제3 사업자(third party)가 제공하는 유료 서비스를 이용하며, 시스템 내부 요소는 아니다. - DNS 조회 결과로 웹 서버의 IP 주소가 반환된다.
- 해당 IP 주소로 HTTP 요청이 전달된다.
- 웹 서버는 요청을 처리하여 HTML 페이지나 JSON 응답을 반환한다.
데이터베이스 분리
사용자 수가 늘어나면 서버 한 대로는 부족하다.
따라서 웹/모바일 트래픽 처리 서버(웹 계층
)와 데이터베이스 서버(데이터 계층)
를 분리하여 독립적으로 확장할 수 있게 한다.
어떤 데이터베이스를 선택할까?
관계형 데이터베이스(RDB)와 비관계형 데이터베이스(NoSQL)의 차이는 다음과 같다.
1. 관계형 데이터베이스
자료를 테이블과 열, 칼럼으로 표현한다. 여러 테이블에 있는 데이터를 그 관계에 따라 join 하여 합칠 수 있다.
2. 비관계형 데이터베이스
CouchDB, Neo4j, MongoDB, Amazon DyamoDB 등이 있다.
다음 네 부류로 나뉜다.
- 키-값 저장소(key-value store)
- 그래프 저장소(graph store)
- 칼럼 저장소(column store)
- 문서 저장소(document store)
비 관계형 데이터베이스는 일반적으로 조인 연산을 지원하지 않는다.
대부분의 상황에서는 관계형 데이터베이스가 최선이지만, 아래의 경우 비관계형 데이터베이스도 고려할 수 있다.
- 매우 낮은 응답 지연시간(latency)이 요구될 때
- 다루는 데이터가 비정형(unstructured)이라 관계형 데이터가 아닐 때
- 데이터(JSON, YAML, XML 등)를 직렬화하거나 역직렬화할 수 있기만 하면 될 때
- 아주 많은 양의 데이터를 저장해야 할 때(빅데이터)
- ex) SNS 친구 관계 및 피드 데이터
수직적 규모 확장 vs 수평적 규모 확장
구분 | 설명 |
---|---|
수직적 확장 (Scale Up) | 한 대의 서버 CPU, RAM 같은 사양을 높이는 방식 |
수평적 확장 (Scale Out) | 서버의 대수를 추가하여 성능을 개선하는 방식 |
수직적 확장의 단점
수직적 확장은 초기 트래픽이 적을 때 단순한 방법이지만 치명적인 단점이 있다.
- 한 대의 서버에 CPU나 메모리를 무한대로 증설하는 데에는 한계가 있다.
- 수직적 규모 확장법은 장애에 대한 자동복구(failover) 방안이라 다중화 방안을 제시하지 않는다.
서버에 장애가 발생하면 웹사이트/앱은 완전히 중단된다.
따라서 대규모 애플리케이션에는 수평적 확장이 적합하다.
로드 밸런서
위 처럼 웹 서버가 직접 클라이언트 요청을 처리하는 설계에는 몇 가지 문제가 있다.
- 웹 서버가 다운되면 사용자는 웹 사이트에 접속할 수 없다.
- 너무 많은 사용자가 접속하여 웹 서버가 한계 상황에 도달하게 되면 응답 속도가 느려지거나 서버 접속이 불가능해질 수도 있다.
이를 해결하려면 부하 분산기 또는 로드밸런서를 도입하는 것이 최선이다.
로드밸런서는 부하 분산 집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.
위 그림을 보면 사용자는 로드밸런서의 공개 IP 주소(public IP address)
로 접속한다.
따라서 웹 서버는 클라이언트의 접속을 직접 처리하지 않는다.
더 나은 보안을 위해, 서버 간 통신에는 사설 IP 주소(private IP address)
가 이용되며, 로드밸런서는 웹 서버와 통신하기 위해 바로 이 사설 주소를 이용한다.
사설 IP 주소는 같은 네트워크에 속한 서버 사이의 통신에만 쓰일 수 있는 IP 주소로, 인터넷을 통해서는 접속할 수 없다.
그림에 나온 대로 부하 분산 집합에 또 하나의 웹 서버를 추가하고 나면 장애를 자동복구하지 못하는 문제는 해소되며, 웹 계층의 가용성은 향상된다.
이게 무슨 말일까?
- 서버 1이 다운되면(offline) 모든 트래픽은 서버 2로 전송되므로 웹 사이트 전체가 다운되는 일이 방지된다. 부하를 나누기 위해 새로운 서버를 추가할 수도 있다.
- 웹사이트로 유입되는 트래픽이 가파르게 증가하면 두 대의 서버로 트래픽을 감당할 수 없는 시점이 오는데, 로드밸런서가 있으므로 걱정하지 않아도 된다. 웹 서버 계층에 더 많은 서버를 추가하기만 하면 로드밸런스가 자동적으로 트래픽을 분산하기 시작할 것이다.
데이터베이스 다중화
웹 계층은 이제 안정적이지만, 데이터베이스가 하나라면 장애 발생 시 위험하다.
따라서 주-부 다중화(Master-Slave Replication)
를 적용한다.
"많은 데이터베이스 관리 시스템이 다중화를 지원한다. 보통은 서버 사이에 주(master)-부(slave) 관계를 설정하고 데이터 원본은 주 서버에, 사본은 부 서버에 저장하는 방식이다." - 위키피디아
- 쓰기 연산(write operation)은 마스터(주 데이터베이스)에서만 지원한다.
- 부 데이터베이스는 주 데이터베이스로부터 그 사본을 전달받으며, 읽기 연산(read operation)만을 지원한다.
- 데이터베이스를 변경하는 명령어들(
insert
,delete
,update
등)은 주 데이터베이스로만 전달되어야 한다.
데이터베이스 다중화의 장점
더 나은 성능
주-부 다중화 모델에서 모든 데이터 변경 연산은 주 데이터베이스 서버로만 전달되는 반면 읽기 연산은 부 데이터베이스 서버들로 분산된다. 병렬로 처리될 수 있는 질의(query) 수가 늘어나므로, 성능이 좋아진다.
안정성(reliability)
데이터를 지역적으로 떨어진 여러 장소에 다중화시켜 놓을 수 있기 때문에, 자연재해 등의 이유로 데이터베이스 서버 가운데 일부가 파괴되어도 데이터는 보존될 것이다.
가용성(availability)
데이터를 여러 지역에 복제해 둠으로써, 하나의 데이터베이스 서버에 장애가 발생하더라도 다른 서버에 있는 데이터를 가져와 계속 서비스할 수 있게 된다.
장애 상황별 동작
이때! 만약 다중화된 데이터베이스 서버 중 하나가 다운되면 무슨 일이 벌어질까?
상황 | 동작 |
---|---|
부 서버 1대 다운 | 읽기 연산은 주 서버로 이동, 새 부 서버가 장애 서버를 대체 |
부 서버 여러 대 중 1대 다운 | 읽기 연산은 나머지 부 서버로 분산, 새 부 서버가 장애 서버를 대체 |
주 서버 다운 (부 서버 1대) | 부 서버가 새로운 주 서버로 승격, 새 부 서버 추가 필요 |
프로덕션(production) 환경에서 벌어지는 일은 이것보다는 사실 더 복잡한데, 부 서버에 보관된 데이터가 최신 상태가 아닐 수 있기 때문이다. 없는 데이터는 복구 스크립트(recovery script)를 돌려서 추가해야 한다.
다중 마스터나, 원형 다중화 방식을 도입하면 도움이 될 수 있지만, 훨씬 복잡하며 이 책에서 다룰 수 있는 범위를 넘어선다.
로드밸런서 + 데이터베이스 다중화를 고려한 최종 설계
이 설계는 다음과 같이 동작한다.
- 사용자는 DNS로부터 로드밸런서의 공개 IP 주소를 받는다.
- 해당 IP 주소로 로드밸런서에 접속한다.
- HTTP 요청은 서버 1이나 서버 2로 전달된다.
- 웹 서버는 부 데이터베이스에서 데이터를 읽고,
- 데이터 추가, 삭제, 갱신 같은 변경 연산은 주 데이터베이스로 전달한다.
이미지 출처
'📝 끄적끄적 > 📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초' 카테고리의 다른 글
3장. 시스템 설계 면접 공략법 (0) | 2025.06.05 |
---|---|
2장. 개략적인 규모 추정 (0) | 2025.06.04 |
1장. 사용자 수에 따른 규모 확장성 - (3) 샤딩, 메시지 큐, 자동화 (0) | 2025.06.01 |
1장. 사용자 수에 따른 규모 확장성 - (2) 캐시, CDN (0) | 2025.06.01 |