
1, 사용자는 도메인 이름을 이용하여 웹사이트에 접속한다. 이 접속을 위해서는 도메인 이름을 도메인 이름 서비스에 질의하여 IP 주소로 변환하는 과정이 필요하다.
2, DNS 조회로 웹 서버의 IP 주소가 반환된다.
3, 해당 IP 주소로 HTTP 요청이 전달된다.
4, 요청을 받은 웹 서버는 HTML 페이지나 JSON 형태의 응답을 반환한다.
사용자가 많아지면 서버 하나로 충분하지 않아서 서버를 여러개 두는 생각을 해야한다.

MySql, orcle, PostgreSQL 등을 RDBMS라고 부른다. 자료를 테이블과 열, 컬럼으로 표현하고, SQL을 사용하여 여러 테이블에 있는 데이터를 그 관계에 따라 JOIN 할 수 있다.
DynamoDB, redis, MongoDB, Neo4j 등이 있으며 4 분류로 나눌 수 있다. key-value 저장소, 그래프 저장소, 컬럼 저장소, 문서 저장소가 있다. 비-관계형 DB는 일반적으로 JOIN을 지원하지는 않는다.
NoSQL을 고려해야할 경우
서버에 고사양 자원을 추가하는 행위이다. 하지만 Scale-up 확장에는 한계가 존재한다. 한 대의 서버에 CPU, 메모리를 무한대로 증성할 수 없고, 비용 또한 비싸다. 또한 장애에 대한 자동복구 방안이나 다중화 방안을 제시하지 않는다. (서버 장애시 웹페이지 완전 중단)
위의 문제를 해결하기 위하여 로드밸런서를 도입할 수 있다.

사용자는 로드밸런서의 Public IP로 접속한다. 서버 간 통신에는 Private IP가 이용되며, 위처럼 스케일 아웃을 통해서 서버를 여러 대로 늘리게 되면 장애를 자동복구하지 못하는 문제도 해소할 수 있고, 웹 계층의 가용성은 향상된다.
많은 데이터베이스에서 다중화를 지원한다. 보통은 서버 사이에 master - slave 관계를 설정하고 데이터 원본은 master 서버에, 사본은 slave 서버에 저장하는 방식이다.
쓰기 연산은 master에서만 지원하고 slave DB는 사본을 전달받고 읽기 연산만 지원한다.

DB 다중화의 장점

DB 다중화와 로드밸런서를 적용한 모습이다.
값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소다.
데이터가 잠시 보관되는 곳으로 DB보다 횔씬 빠르다. 또한 데이터베이스의 부하도 줄일 수 있으며 규모를 독립적으로 확장시키는 것도 가능해진다.

위의 사진은 읽기 주도형 캐시 전략이라고 부른다. 이렇게 사용하는 것 이외에도 캐시 전략이 있는데, 캐시할 데이터 종류, 크기, 액세스 패턴에 맞는 캐시 전략을 선택하면 된다.
CDN은 정적 콘텐츠를 전송하는 데 쓰이는, 지리적으로 분산된 서버의 네트워크이다. 이미지, 비디오, CSS, JavaScript 파일 등을 캐시할 수 있다. 요청 경로, 질의 문자열, 쿠키, 요청 헤더 등의 정보에 기반하여 HTML 페이지를 캐시할 수 있다.


웹 계층을 수평적으로 확장하는 방법을 고려해보자. 이를 위해서는 상태 정보(사용자 세션 데이터와 같은 정보)를 웹 계층에서 제거해야 한다. 바람직한 전력은 상태 정보를 관계형 DB나 NoSQL 같은 지속성 저장소에 보관하고, 필요할 때 가져오도록하는 방법이다.
상태 정보를 보관하는 서버는 클라이언트 정보, 즉 상태를 유지하여 요청들 사이에 공유되도 하지만, 무상태 서버에는 이런 장치가 없다.

위의 그림에서는 사용자 A는 서버1에서만 인증이 가능하기 때문에 이런 문제를 해결하기위에 대부분 로드밸런서가 이를 지원하는 고정 세션이라는 기능을 제공한다. 하지만 이는 로드밸런서에 부담을 주며, 로드밸런스 뒷단에 서버를 추가하거나 제거하기도 까다로워진다.

이러한 구조에서는 사용자로부터 HTTP 요청은 어떤 웹 서버로도 전달될 수 있다. 웹 서버는 상태 정보가 필요한 경우 공유 저장소로부터 데이터를 가져온다. 따라서 상태 정보는 웹 서버로부터 물리적으로 분리되어 있다.

이러한 공유 저장소는 Redis와 같은 캐시 시스템일 수도 있으며, NoSQL일 수도 있다.

위의 그림은 데이터 센터를 2개 이용하는 사례이다. 장애가 없는 상황에서는 사용자는 가까운 데이터 센터로 안내된다. 이 절차를 지리적 라우팅이라고 부른다. 지리적 라우팅에서의 geoDNS는 사용자의 위치에 따라 도메인 이름을 어떤 IP 주소로 변환할지 결정할 수 있도록 해주는 DNS 서비스이다.
메시지 큐는 메시지의 무손실을 보장하는, 비동기 통신을 지원하는 컴포넌트다. 메시지 큐에는 보통 소비자 혹은 구독자라 불리는 서비스 혹은 서버가 연결되어 있으며, 메시지에 받아 그에 맞는 동작을 수행하는 역할을 한다.

메시지 큐를 이용하면 서비스 또는 서버 간 결합이 느슨해지며, 규모 확장성이 보장되어야 하는 안정적 애플리케이션을 구성하기 좋다.
로그, 메트릭, 자동화는 소규모의 사이트에서는 추천되지 않지만 웹 사이트의 사업 규모가 커지고 나면, 필수적으로 투자해야하는 부분이다.

저장할 데이터가 많아지면 데이터베이스에 대한 부하도 증가한다. 데이터베이스의 규모 확장에는 두가지 접근법이 존재한다.
수직적 규모 확장법은 기존 서버에 더 많은, 또는 고성능의 자원을 증설하는 방법이다.
1, 데이터베이스 서버 하드웨어에는 한계가 있으므로 CPU, RAM 등을 무한 증설할 수 없다.
2, SPOF로 인한 위험성이 크다.
3, 비용이 비싸다.
데이터베이스의 수평적 확장은 샤딩이라고도 부르는데, 더 많은 서버를 추가함으로써 성능을 향상시킬 수 있도록 한다. (샤드는 작은 단위로 분활하는 기술을 말한다.)

모든 샤드는 같은 스키마를 쓰지만 샤드에 보관되는 데이터 사이에는 중복이 없다.

샤딩 전략을 구현할 때 고려해야 할 가장 중요한 것은 샤딩 키를 어떻게 정하느냐 하는 것이다. 샤딩 키를 올바른 데이터베이스에 질의를 보내어 데이터 조회나 변경을 처리하므로 효율을 높일 수 있기 때문이다.
1, 데이터의 재 샤딩
데이터가 너무 많아져서 하나의 샤드로는 더 이상 감당하기 어려울 때
샤드 간 데이터 분포가 균등하지 못하여 어떤 샤드에 할당된 공간 소모가 다른 샤드에 비해 빨리 진행될 때
2, 유명 인사: 핫스팟 키 문제라고도 부르는데, 특정 샤드에 쿼리가 집중되어 서버에 과부하가 걸리는 문제
3, 조인과 비정규화
일단 하나의 데이터베이스를 여러 샤드 서버로 쪼개고 나면, 여러 샤드에 걸친 데이터를 조인하기가 힘들어진다. 이를 해결하는 한 가지 방법은 데이터베이스를 비정규화하여 하나의 테이블에서 쿼리가 수행될 수 있도록 하는 것이다.
