# 1장

이번 장에서는 한 명의 사용자를 지원하는 시스템에서 시작하여, 최종적으로는 몇백만 사용자를 지원하는 시스템을 설계해볼 것이다.

#### 단일 서버

* 모든 컴포넌트가 단 한대의 서버에서 실행된다.
* 웹 앱, 데이터베이스, 캐시 등이 전부 서버 한 대에서 실행된다.

#### 데이터베이스

* 사용자가 늘면 서버 하나로는 충분하지 않아서 여러 서버를 두어야 한다.
* 하나는 웹/모바일 트래픽 처리 용도, 다른 하나는 데이터베이스용이다.
* 어떤 데이터베이스를 사용할 것인가?
  * 관계형 데이터베이스
    * 40년 이상 시장에서 살아남아 잘 사용되어 온 시스템
  * 비관계형
    * 다음과 같은 경우 바람직하다
      * 아주 낮은 응답 지연시간이 요구됨
      * 다루는 데이터가 비정형이라 관계형 데이터가 아님
      * 데이터(JSON, YAML, XML 등)를 직렬화하거나 역직렬화 할 수 있기만 하면 됨
      * 아주 많은 양의 데이터를 저장할 필요가 있음

#### 수직적 규모 확장 vs 수평적 규모 확장

* 수직적 규모 확장 - 서버에 고사양 자원을 추가하는 행위
  * 한계가 있으며, failover나 다중화 방안을 제시하지 않는다. 장애가 발생하면 서비스는 완전히 중단된다.
* 수평적 규모 확장 = 스케일 아웃 = 더 많은 서버를 추가하는 행위

#### 로드 밸런서

로드밸런서는 부하 분산 집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.

#### 데이터베이스 다중화

* 쓰기 연산은 마스터에서만 지원한다.
* 부 데이터베이스는 주 데이터베이스로부터 그 사본을 전달받으며, 읽기 연산(read operation)만을 지원한다.
* 더 나은 성능, 안정성, 가용성을 얻을 수 있다.

#### 캐시

* 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소.
* 여러 고려사항들이 있다.
  * 어떻게 만료시킬 것인가?
  * 일관성은 어떻게 유지되는가? 캐시가 여러 개 있는 경우?
  * 장애에는 어떻게 대처할 것인가? 캐시 서버가 1대일 경우 해당 서버는 단일 장애 지점이 될 수 있다.
  * 캐시 메모리는 얼마나 크게 잡을 것인가?
  * 데이터 방출 정책은 무엇인가?

#### CDN

* CDN은 정적 콘텐츠를 전송하는 데 쓰이는, 지리적으로 분산된 서버의 네트워크이다. 이미지, 비디오, CSS, Javascript 파일 등을 캐시할 수 있다.

#### 무상태(Stateless) 웹 계층

* 수평적 확장을 위해선, 상태 정보(사용자 세션 데이터와 같은)를 웹 계층에서 제거하여야 한다.

#### 데이터센터

여러분의 웹사이트가 매우 빨리 성장하여 전 세계 사용자들의 이목을 받는 시점이 왔다고 해보자. 가용성을 높이고 전 세계 어디서도 쾌적하게 사용할 수 있도록 여러 데이터 센터를 지원하는 것이 필수다.

#### 메세지 큐

* 시스템을 더 큰 규모로 확장하기 위해서는 시스템의 컴포넌트를 분리하여, 각기 독립적으로 확장될 수 있도록 해야한다. 메세지큐는 분산 시스템이 이 문제를 풀ㅇ기 위해 채용하는 핵심적 전략 중 하나다.

이번 장을 마무리하며, 시스템 규모 확자을 위해 살펴본 기법들을 정리해보면 다음과 같다.

* 웹 계층은 무상태 계층으로
* 모든 계층에 다중화 도입
* 가능한 한 많은 데이터를 캐시할 것
* 여러 데이터 센터를 지원할 것
* 정적 콘텐츠는 CDN을 통해 서비스할 것
* 데이터 계층은 샤딩을 통해 그 규모를 확장할 것
* 각 계층은 독립적 서비스로 분할할 것
* 시스템을 지속적으로 모니터링하고, 자동화 도구들을 활용할 것
