'가상 면접 사례로 배우는 대규모 시스템 설계 기초' 책 기반 정리!!!!
1️⃣ 사용자 수에 따른 규모 확장성
💻 단일 서버

아주 간단한 서버의 사용자 요청 처리 흐름
- 사용자는 도메인 이름을 검색해서 웹사이트에 접속. 이때, DNS (Domain Name System)에 질의하여 IP 주소로 변환하는 과정을 거침
- 이때 DNS는 제3 사업자가 제공하는 유료 서비스를 이용하기에 우리 시스템의 일부는 아님
-
DNS 조회 결과로 반환된 IP 주소로 HTTP 요청을 전달
-
요청을 받은 웹 서버는 HTML 홈페이지나 JSON 형태의 응답 반환
실제 요청은 두 가지 종류(웹 앱, 모바일 앱)의 단말로부터 오는 실제 요청
-
웹 애플리케이션: 비지니스 로직, 데이터 저장 등을 처리하기 위해 자바, 파이썬 등의 서버 구현용 언어를 사용하고 표현용으로는 자바 스크립트 등의 클라이언트 구현용 언어를 사용
-
모바일 앱: 모바일 앱과 웹 서버 간의 통신을 위해서는 HTTP 프로토콜을 이용하고 보통 JSON 형식의 응답 데이터가 반환
💻 데이터베이스

사용자가 증가함에 따라 서버를 확장하면 웹/모바일 트래픽 처리용 서버 하나와 데이터베이스 서버를 분리해서 각각을 독립적으로 확장해나감
🌀 데이터베이스 종류
관계형 데이터베이스
- 관계형 데이터베이스는 관계형 데이터베이스 관리 시스템 'RDBMS'라고도 불림 ex) MySQL, 오라클 데이터베이스, PostgreSQL 등
- 자료를 텡블과 열, 칼럼으로 표현
- SQL을 사용하면 여러 테이블에 있는 테이블을 관계에 따라 조인할 수 있음
비관계형 데이터베이스
- NoSQL이라고도 불림 ex) CouchDB, Neo4j, Cassandra, Amazon DynamoDB
- NoSQL은 '키-값 저장소', '그래프 저장소', '칼럼 저장소', '문서 저장소' 네 가지로 불리
- 일반적으로 조인 연산은 지원되지 않음
대부분 관계형 데이터베이스를 사용하지만 아래의 경우 비관계형 데이터베이스가 적합함
- 아주 낮은 응답 지연시간이 요구되는 경우
- 다루는 데이터가 비정형이라 관계형 데이터가 아닌 경우
- 데이터를 직렬화하거나 역질렬화하기만 하면 되는 경우
- 아주 많은 양의 데이터를 저장할 필요가 있는 경우
💻 수직적 규모 확장 vs 수평적 규모 확장
수직적 규모 확장
수평적 규모 확장
- '스케일 아웃'이라고도 하는 수평정 규모 확장은 더 많은 서버를 추가하여 성능을 개선하는 행위
- 대규모 애플리케이션을 지원할 때는 수평적 확장이 적합
🌀 로드밸런서
: 웹 계층의 장애 복구나 다중화를 지원하는 기술
- 사용자가 웹 서버에 바로 연결하는 경우, 웹 서버가 다운되거나 너무 많은 사용자가 접속하면 사용자가 서비스를 이용하는데 어려움이 있음. 이런 경우를 방지하기 위해 로드밸런서를 도입

- 로드밸런서는 부하 분산 집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 함. 쉽게 말하면 트래픽을 분산하기 위해 적절히 서버를 선택해주는 애라고 생각하면 됨
- 사용자가 웹 서버로 바로 연결되는게 아니라 로드밸런스의 공개 IP 주소로 접속하게 됨
- 이때, 보안을 위해 서버 간 통신에서는 사설 IP 주소를 이용
사설 IP 주소란?
: 같은 네트워크에 속한 서버 사이의 통신에만 쓰이는 IP 주소로, 인터넷을 통해서는 접속할 수 없음
로드밸런서가 동작하는 방식은 다음과 같음
- 서버 1이 다운되면 모든 트래픽은 서버 2로 전송되기 때문에 웹 사이트 전체가 다운되는 일이 방지됨. 혹은 새로운 서버를 추가할 수도 있음
- 웹사이트로 유입되는 트래픽이 많아지면 로드밸런서를 통해 자동적으로 트래픽을 분산하게 됨
🌀 데이터베이스의 다중화
: 데이터 계층의 장애복구나 다중화를 지원하는 기술

-
보통 서버 사이에 주(master)-부(slave) 관계를 설정하고 데이터 원본은 주서버에, 사본은 부서버에 저장
-
쓰기 연산은 마스터에서만 지원하고 부 데이터베이스는 주 데이터베이스로부터 사본을 전달받음
-
데이터베이스를 변경하는 명령어는 주 데이터베이스로만 전달되어야 함
-
대부분의 애플리케이션은 쓰기 연산보다 읽기 연산을 더 많이 하기에 부 데이터베이스의 수가 더 많음
-
장점
- 성능 향상: 데이터 변경 연산은 주 데이터베이스 서버로, 읽기 연산은 부 데이터베이스 서버로 분산되어 병렬로 처리되는 쿼리의 수가 늘어나 성능이 좋아짐
- 안정성 혹은 신뢰성: 데이터베이스 일부가 파괴되어도 데이터는 보존됨. 지역적으로 떨어진 여러 장소에 다중화시켜놓을 수 있음
- 가용성: 데이터를 여러 지역에 복제해 둠으로써 하나의 데이터베이스 서버에 문제가 발생해도 다른 서버에 있는 데이터를 사용하면 됨
Q. 데이터베이스 서버 중 하나가 다운되면?
1. 부 서버가 한대 뿐인데 다운된 경우, 읽기 연산은 일시적으로 모두 주 데이터베이스로 전달되고 새로운 부 데이터베이스 서버가 장애 서버를 대체할 것
2. 부 서버가 여러 대인 경우, 읽기 연산은 나머지 부 데이터베이스 서버로 분산될 것
3. 주 서버가 다운되면, 한 대의 부 데이터베이스가 새로운 주 서버로 대체될 것이고 새로운 부서버가 추가될 것임
4. 부 서버에 보관된 데이터가 최신 상태가 아닐 수도 있기에 없는 데이터는 복구 스크립트를 돌려서 추가해야함
+) 다중 마스터나 원형 다중화 방식을 도입하면 도움될 수 있으나 복잡함

로드밸런서와 데이터베이스 다중화 둘 다 적용한 설계는 위와 같음
- 사용자는 DNS로부터 로드밸런스의 공개 IP 주소를 받아서 접속함
- HTTP 요청이 로드밸런스에 의해 서버1이나 서버2로 전달됨
- 웹 서버는 사용자의 데이터를 부 데이터베이스 서버에서 읽음
- 웹 서버에서 데이터 변경 연산이 필요한 경우 주 데이터베이스로 전달됨
💻 캐시
: 값 비싼 연산 결과나 자주 참조되는 데이터를 메모리 안에 두고 빨리 처리될 수 있도록 하는 저장소
🌀 캐시 계층
- 데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠름
- 성능 개선 및 데이터베이스의 부하를 줄일 수 있음

1. 요청을 받은 웹 서버가 캐시에 데이터가 있는지 확인
2. 저장되어있다면 해당 데이터 클라이언트에 반환 -> '주도형 캐시 전략'
** 캐시 전략은 캐시할 데이터의 종류, 크기, 엑세스 패턴에 따라 다양하므로 맞는 전략 사용하면 됨
🌀 캐시 사용 시 유의할 점
Q1. 캐시는 어떤 상황에 바람직한가?
A1. 데이터 갱신이 자주 일어나지 않지만 참조가 빈번하게 일어나는 경우
Q2. 어떤 캐시를 데이터에 두어야하는가?
A2. 캐시는 휘발성이기 때문에 영속적으로 보관할 데이터를 두는 것은 바람직하지 않음
Q3. 캐시에 보관된 데이터는 어떻게 만료되는가?
A3. 캐시 만료 정책을 만료해두어야함. 너무 짧지도, 너무 길어서도 안됨
Q4. 장애에는 어떻게 대처하는가?
A4. 여러 대의 캐시 서버를 둠으로써 SOF 방지
Q5. 캐시 사이즈의 크기는?
A5. 캐시 메무리가 너무 작으면 데이터가 너무 자주 캐시에서 밀려나서 성능이 떨어지게 됨. 이를 방지하기 위해 캐시 메로리를 과할당하면 됨
Q6. 데이터 방출 정책은?
A6. 일반적으로 LRU(Least Recently Used) 정책을 사용하거나 LFU, FIFO 등이 있어 경우에 맞게 사용하면 됨
💻 콘텐츠 전송 네트워크 (CDN)
: 정적 콘텐츠를 전송하는 데 쓰이는 지리적으로 분산된 서버의 네트워크
- 이미지, 비디오, CSS, Javascript 등을 캐시할 수 있음

- 사용자 A가 이미지 URL을 이용해 image.png에 접근. 이때 URL의 도메인은 CDN 서비스 사업자가 제공
- CDN 서버 캐시에 해당 이미지가 없는 경우, 서버는 원본 서버에 요청하여 파일을 가져옴
+) 원본 서버는 웹 서버이거나 S3같은 온라인 저장소
- 원본 서버가 파일을 CDN 서버에 반환하고 응답 HTTP 헤더에는 해당 파일의 TTL 값이 들어있음
- CDN 서버는 파일을 캐시하고 사용자 A에게 반환
- 다른 사용자가 해당 이미지에 대한 요청을 하게 되면 만료되지 않은 이미지의 경우 캐시를 통해 처리됨

CDN과 캐시가 추가되면 정적 콘텐츠는 웹 서버를 통해 서비스되지 않고 CDN을 통해 제공하고 캐시를 통해 데이터베이스 부하를 줄임으로써 성능 개선
💻 무상태 웹 계층
- 웹 계층을 수평적으로 확장하기 위해서는 사용자 세션 데이터 등의 상태 정보를 웹 계층에서 제거해야 함
- 상태 정보를 관계형 데이터베이스나 NoSQL 같은 지속성 저장소에 보관하고 필요할 때 가져오도록 하는 전략으로 구성된 웹 계층을 무 상태 웹 계층이라함
🌀 상태 정보 의존적인 아키텍처

상태 정보를 보관하는 아키텍처의 경우 같은 클라이언트로부터의 요청은 항상 같은 서버로 전송되어야하는 문제가 존재함
🌀 무상태 아키텍처

- 상태 정보가 필요할 경우 공유 저장소로부터 데이터를 가져옴
- 상태 정보가 웹 서버로부터 물리적으로 분리되어있기에 단순하고, 안정적이며 규모 확장이 쉬움

- 세션 데이터를 웹 계층에서 분리하고 지속성 데이터 보관소에 보관하도록 함. 공유 저장소는 관계형 데이터베이스나 캐시 시스템, NoSQL일 수 있음
- '1 자동 규모 확장'은 상태 정보가 웹 서버로부터 제거되었기 때문에 트래픽 양에 따라 웹 서버를 넣거나 뺌으로써 자동으로 규모를 확장할 수 있게됨 즉 오토 스케일링이 가능케됨
💻 데이터 센터

- 장애가 없는 상황에서 사용자에게 가까운 데이터 센터를 이용하게 되는데, 이를 지리적 라우팅이라고함
- 지리적 라우팅에서 getoDNS는 사용자의 위치에 따라 도메인 이름을 어떤 IP 주소로 변환할지 결정할 수 있도록 해주는 서비스

- 하나의 데이터 센터에 장애가 발생하면 모든 트래픽이 장애가 없는 데이터 센터로 전송됨
🌀 다중 데이터센터 아키텍처 고려사항
1. 트래픽 우회
: 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야함
2. 데이터 동기화
: 데이터 센터마다 별도의 데이터베이스를 사용한다면 데이터센터마다 다른 데이터가 존재할 수 있음. 이런 상황을 막기 위해 데이터를 여러 데이터 센터에 걸쳐 다중화함
3. 테스트와 배포
: 여러 데이터 센터를 사용하는 경우 웹 사이트를 여러 위치에서 테스트하는 것이 중요함
💻 메시지 큐

- 메시지 큐란, 메시지의 무손실을 보장하는 비동기 통신 컴포넌트로 생산자가 메시지 큐에 메시지를 발행하면 큐에 연결되어있는 소비자가 메시지를 받아 그에 맞는 동작을 수행함
- 메시지 큐를 이요하면 서비스, 서버 간 결합이 느슨해져서 규모 확장하기에 용이함
- 또, 프로세스가 다운되어 있어서 메시지를 발행할 수 있음
- 예를 들어, 시간이 오래 걸리는 프로세스인 사진 보정 애플리케이션의 경우 비동기적으로 사진 보정 작업 프로세스를 처리하면 됨
💻 로그, 메트릭, 자동화

- 로그: 시스템의 오류와 문제를 보다 쉽게 찾아낼 수 있도록 모니터링이 필요
- 메트릭: 메트릭을 수집하면 사업 현황에 관한 유용한 정보 및 시스템의 현재 상태를 손쉽게 파악할 수 있음
- 호스트 단위 메트릭: CPU, 메모리, 디스크 I/O에 관한 메트릭
- 종합 메트릭: 데이터베이스 계층의 성능, 캐시 계층의 성능
- 핵심 비지니스 메트릭: 일별 능동 사용자, 수익, 재방문 등
- 자동화: CI/CD 등의 자동 빌드, 테스트, 배포 등으로 개발 생산성 향상 가능
💻 데이터베이스의 규모 확장

🌀 수직적 확장
- 고성능의 자원을 확장하는 방법으로 하드웨어 증설에는 한계가 있기도 하고 비용이 많이 드는 문제점이 있음
🌀 수평적 확장
- 데이터베이스의 수평적 확장은 '샤딩 (sharding)'이라고 부름
- 샤딩은 대규모 데이터베이스를 샤드라고 부르는 작은 단위로 분할하는 기술
- 샤드는 같은 스키마를 쓰지만 샤드에 보관되는 데이터 사이에는 중복이 없음

- 위 사진의 경우, 사용자 아이디에 따라 정함
- 샤딩 전략을 구현할 때 샤딩 키를 어떻게 정하는지가 가장 중요함 -> 데이터를 고르게 분할하는 것이 목적
- 데이터의 재 샤딩: 데이터가 너무 많아져서 하나의 샤드로 감당하기 어려울 때, 샤드 간 데이터 분포가 균등하지 못해 특정 샤드의 공간 소모가 다른 샤드에 비해 빨리 진행될 때
- 유명인사 문제: 특정 샤드에 쿼리가 집중되어 서버에 과부하가 걸림.
ex) 유명인사가 같은 샤드에 저장되는 데이터베이스의 경우 이 샤드에 많은 읽기 연산이 몰려 과부하가 걸리게 될 것임
- 조인과 비정규화: 하나의 데이터베이스를 여러 샤드 서버로 나누게 되면 여러 샤드에 걸친 데이터베이스를 조인하기 어려워짐. 이를 해결하기 위해 데이터베이스를 비정규화하여 하나의 테이블에서 질의가 수행될 수 있도록 함

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