사용자 수에 따른 규모 확장성 (1) – 웹서버, 데이터베이스, 로드밸런서
가상 면접 사례로 배우는 대규모 시스템 설계 기초 - System Design Interview
1장 사용자 수에 따른 규모 확장성 : 어떻게 수백만 사용자를 지원하는 시스템을 설계할 것인가.
단일 서버
사용자는 도메인 이름을 이용하여 웹 사이트에 접속한다.
- 이러한 접속을 위해서 DNS에 질의하여 IP 주소로 변환한다.
(DNS는 제3 사업자(third party)를 통해 제공되므로 우리 시스템의 일부는 아님) - DNS 조회 결과로 IP 주소가 반환된다.
- 해당 IP 주소로 HTTP 요청이 전달된다.
- 요청을 받은 웹 서버는 HTML 페이지나 JSON과 같은 형태의 응답을 반환한다.
요청들은 두가지 종류의 단말로부터 오는데 하나는 웹 앱이고 다른 하나는 모바일 앱이다.
(모바일 앱에서는 데이터 포맷으로 JSON이 간결함 덕에 널리 쓰인다.)
* IP는 Internet Protocol의 약자이다.
데이터베이스 분리
사용자가 늘면 서버 하나로는 충분하지 않아서 여러 서버를 두어야 한다.
웹/모바일 트래픽 처리 서버(웹 계층)와 데이터베이스 서버(데이터 계층)를 분리하면 그 각각을 독립적으로 확장해 나갈 수 있게 된다.
어떤 데이터베이스를 사용할 것인가?
관계형 데이터베이스
전통적인 데이터베이스
Relational Database Management System, RDBMS
Mysql, 오라클 데이터베이스, PostgreSQL 등
데이터를 테이블과 열, 칼럼으로 표현한다.
여러 테이블에 있는 데이터를 관계에 따라 조인(join) 하여 합칠 수 있다.
비-관계형 데이터베이스
NoSQL
CouchDB, Neo4j, Cassandra, HBase, Amazon DynamoDB 등
NoSQL의 네가지 분류
- 키-값 저장소(key-value store)
- 그래프 저장소(graph store)
- 칼럼 저장소(column store)
- 문서 저장소(document store)
일반적으로 조인은 지원하지 않는다.
NoSQL이 바람직한 경우
- 아주 낮은 응답 지연 시간이 요구됨
- 데이터가 비정형(unstructured)이라 관계형 데이터가 아님
- 데이터를 직렬화하거나 역직렬화 할 수 있기만 하면 됨
- 아주 많은 양의 데이터를 저장할 필요가 있음
* 직렬화는 객체를 바이트스트림으로 변환하는 것을 의미하며, 역직렬화는 바이트 스트림을 객체로 다시 변환하는 것을 의미한다. 바이트스트림으로 변환하는 이유는 객체를 데이터화해서 다른 시스템에서도 해당 객체를 이해할 수 있게 하기 위함이다.
* SQL은 구조적 쿼리 언어(Structured Query Language)의 약자이다.
수직적 규모 확장 vs 수평적 규모 확장
수직적 규모 확장 (Scale Up)
서버에 고사양 자원을 추가함
수직적 규모 확장에는 한계가 있다. (한 대의 서버에 CPU나 메모리를 무한대로 증설할 방법은 없다)
수평적 규모 확장 (Scale Out)
더 많은 서버를 추가하여 성능을 개선
장애에 대한 자동복구(failover) 방안이나 다중화(redundancy) 방안을 제시하지 않는다. 서버에 장애가 발생하면 웹사이트/앱은 완전히 중단된다.
→ 따라서, 대규모 애플리케이션을 지원하는 데는 수평적 규모 확장법이 적절하다.
로드밸런서
부하 분산 집합(load balancing set)에 속한 우엡 서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.
웹 서버는 클라이언트의 접속을 직접 처리하지 않는다. 더 나은 보안을 위해, 서버간 통신에는 사설 IP 주소(private IP address)가 이용된다. 사설 IP 주소는 같은 네트워크에 속한 서버 사이의 통신에만 쓰일 수 있는 IP 주소로 인터넷을 통해서는 접속할 수 없다. 로드밸런서는 웹 서버와 통신하기 위해 바로 이 사설 주소를 이용한다.
부하 분산 집한에 또 하나의 웹 서버를 추가하고 나면 장애를 자동복구하지 못하는 문제(no failover)는 해소되며, 웹 계층의 가용성(availability)은 향상된다.
서버 1이 다운(offline)되면 모든 트래픽은 서버 2로 전송된다. 이를 통해 웹 사이트 전체가 다운되는 일이 방지된다. 부하를 나누기 위해 더 많은 서버를 추가할 수 있다.
여기서 든 궁금증은 “웹 서버는 클라이언트의 접속을 직접 처리하지 않는다.” 라고 되어있는 부분이였다.
그러면 서버 2개 감당하는 트래픽이 전부 로드밸런서를 통해서 간다는 것인데 그에 대한 부하는 어떻게 되는걸까?그에 대한 답변은 다음과 같았다.
우선 로드 밸런서는 웹 트래픽과 달리 요청을 처리하는 역할은 하지 않는다. 그렇기 때문에 사용자의 요청 자체로 인해 걸리는 부하는 웹서버에 걸리는 것보다 적다.
하지만 로드 밸런서는 요청 분산뿐만 아니라, 서버 상태 모니터링, 장애 대응, 보안 등의 다양한 기능을 수행하기 때문에 그로 인한 부하가 걸릴 수도 있다.