Skip to content

Commit

Permalink
[Add] ✍ 1장. 사용자 수에 따른 규모 확장성 (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
jun108059 committed Jun 18, 2023
1 parent 3a1cda8 commit fa92025
Showing 1 changed file with 129 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# 1장. 사용자 수에 따른 규모 확장성

작은 시스템에서 수백만 사용자를 지원하는 시스템으로 확장할 수 있는 `시스템 설계`를 알아본다.

1. 적은 트래픽을 처리할 수 있는 서버
2. 트래픽 증가에 따른 웹 서버 확장성 및 고가용성, 내결함성 보장하기 위한 로드밸런서
3. 데이터의 안정성과 고가용성을 보장하기 위한 다중화
4. 빠른 응답과 성능을 위한 캐시, CDN

## 1. 단일서버

> 적은 사용자를 대상으로 서비스할 때는 하나의 서버만 구성해도 좋다.
- 모든 컴포넌트가 한 대의 서버에서 실행되는 시스템
- 컴포넌트 : 웹, 앱, 데이터베이스,캐시 등

![image](https://github.com/jun108059/til/assets/42997924/051fcedf-c8cc-4b2c-a9a2-70332573a3d2)

1. 사용자는 도메인 이름(`api.mysite.com`)을 이용해 웹사이트에 접속
2. DNS 서버에서 IP 주소 반환(`15.125.23.215`) → 우리 서비스는 아니다
3. 해당 IP 주소(`15.125.23.215`)로 HTTP 요청을 전달
4. HTML 페이지 응답(또는 JSON 응답)

## 2. 데이터베이스

> 사용자가 늘면 서버 하나로 충분하지 않다. 웹/모바일 요청 트래픽 처리 용도와 DB 처리 서버를 나눠보자
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/58888d6d-17f4-4173-97b7-ae80b69ed957/Untitled.png)

- 웹/모바일 트래픽 처리용도의 서버(웹 계층)와 데이터베이스용 서버(데이터 계층)를 분리할 목적
- 먼저 내가 설계하고자 하는 시스템에 어떤 Database를 사용할지 결정할 필요가 있다
- 보통 RDBMS와 NoSQL 둘중 하나를 선택할 수 있는데, 그 차이를 알아보자

### 2-1. RDBMS vs NoSQL

RDBMS와 NoSQL은 데이터를 저장하고 조회하는 방식에 중요한 차이가 있다.


| 항목 | RDBMS | NoSQL |
|--------|------------------------------------------------------|------------------------------------------------------------------------------|
| 데이터 구조 | 엄격한 스키마에 따라 테이블 형태로 데이터를 저장하고, 각 테이블은 행과 열로 구성 | 스키마가 유연하며, 키-값 (Key-value), 그래프(graph), 칼럼(column), 문서(document)의 데이터 모델을 지원 |
| 관계 | 테이블 간의 관계를 정의할 수 있으며, JOIN 연산을 이용해 관계형 데이터를 쿼리할 수 있음 | 대부분의 NoSQL 데이터베이스는 JOIN 연산을 지원하지 않는다. 관계는 주로 애플리케이션 레벨에서 관리 |
| 확장성 | 주로 수직 확장(더 빠른 하드웨어를 사용)을 통해 처리능력을 증가 | 수평 확장 (더 많은 서버를 추가)이 용이하며, 대량의 데이터를 분산 처리하는 데 적합 |
| 트랜잭션 | ACID(원자성, 일관성, 격리성, 지속성)보장 | 일부 NoSQL 데이터베이스는 ACID를 지원하지만, 대부분은 유연한 일관성 모델을 사용하여 성능을 최적화 |
| 사용 사례 | 복잡한 쿼리와 트랜잭션 처리가 필요한 애플리케이션, 구조화된 데이터에 대한 작업에 적합 | 큰 규모의 데이터를 다루거나, 데이터 구조가 빈번하게 변경되는 경우, 빠른 읽기/쓰기가 요구되는 애플리케이션에 적합 |

**비-관계형(NoSQL) 데이터베이스가 좋은 선택일 수 있는 경우**

- 아주 낮은 응답 지연시간(latency) 필요
- Key-Value, Document 등과 같은 데이터 모델들은 RDB의 테이블 구조보다 빠른 조회 속도
- 특히 Key-Value 저장 방식의 NoSQL은 간단한 조회 및 저장 작업에 있어 아주 빠른 응답시간을 제공
- 다루는 데이터가 비정형(unstructured) 데이터인 경우
- 스키마가 유연하기 때문에, 구조가 정해져있지 않거나 빈번하게 변경되는 비정형 데이터를 쉽게 저장하고 관리할 수 있음(JSON 형태의 데이터를 저장하고 조회하는데 최적화된 Document 기반의 NoSQL 데이터베이스를 사용 가능)
- 데이터를 직렬화/역직렬화 할 수만 있으면 되는 경우
- NoSQL은 데이터를 쉽게 직렬화/역직렬화하여 저장하고 조회 가능
- 특히, JSON을 사용하는 웹애플리케이션에서 NoSQL은 데이터를 바로 데이터베이스에 저장하거나 조회할 수 있기 때문에 유용함
- 아주 많은 양의 데이터를 저장할 필요가 있는 경우
- NoSQL은 일반적으로 분산 시스템을 지원하기 때문에, 많은 양의 데이터를 저장하고 처리하는데 적합
- 데이터를 여러 노드에 분산 저장함으로써, 높은 수준의 확장성을 제공하며, 대용량 데이터를 효율적으로 처리 가능

## 3. 수직적 규모 확장 / 수평적 규모 확장

> 사용자가 더 많아지면 서버에서 처리할 수 있는 성능을 개선해야 한다(서버 추가, 서버 장비 업그레이드)
- Scale Up(수직적 규모 확장) : 서버에 고사양 자원을 추가(CPU, RAM 등)
- Scale Out(수평적 규모 확장) : 더 많은 서버를 추가

### 3-1. Scale Up과 Scale Out 비교

| | 스케일 업 (Scale-up) | 스케일 아웃 (Scale-out) |
|-----|-------------------------------------------------------------------|-------------------------------------------------------------------|
| 정의 | 기존 하드웨어의 성능을 향상시키는 방법 | 새로운 하드웨어를 추가하는 방법 |
| 장점 | 1. 쉽고 간단한 확장 방법 <br> 2. 성능 개선이 직관적이며 빠름 <br> 3. 기존 시스템에 영향을 덜 미침 | 1. 병렬 처리에 적합 <br> 2. 비용 효율적인 확장 가능 <br> 3. 고장 시스템의 영향 최소화 |
| 단점 | 1. 하드웨어의 한계로 인한 확장성 제한 <br> 2. 높은 비용 발생 가능 <br> 3. 고장 시 전체 시스템 영향 | 1. 복잡한 구성 관리 <br> 2. 데이터 불일치 문제 발생 가능 <br> 3. 효율적인 분산 처리 알고리즘이 필요 |

- 서버로 유입되는 트래픽이 적을 때는 쉽고 간단한 방법인 Scale-up이 좋은 선택이 될 수 있다.
- 하지만 우리는 `대규모 시스템 설계`가 목적이기 때문에 확장성과 안정성 측면에서 Scale-out이 더 적합하다.

### 3-2. 로드밸런서

> Scale-out을 통해 새로운 서버를 추가했기 때문에, 사용자 요청을 효율적으로 분산하려면 로드밸런서가 필요하다
![image](https://github.com/jun108059/til/assets/42997924/aded1170-e2ec-4e30-aba6-b942bea3f0d9)

- 부하 분산 집합(load balancing set)에 속한 웹 서버들에게 트래픽 부하를 고르게 분산
- 로드밸런서를 public ip로 두고 내부에선 private ip로 이용 → 보안을 위함

**장애 복구 문제와 가용성 향상**

- 서버 1이 죽으면, 모든 트래픽은 서버 2로 전송되기 때문에 사용자 요청을 처리할 수 있음
- 트래픽이 너무 많아지면 웹 서버 계층에 서버를 추가해주면, 로드밸런서가 자동으로 트래픽을 분산

### 3-3. **데이터베이스 다중화**

> 웹 계층은 로드밸런서 덕분에 안정적인 대규모 서비스 운영이 가능하다. 데이터베이스 계층도 살펴보자
DB 서버가 하나일 때도 웹 계층과 마찬가지로 장애 상황이 발생하면 시스템 전체가 정상 동작할 수 없다.

다중화를 통해 이를 해결해보자.

- DB서버 사이에 Main-Replica 관계를 설정하고 데이터 원본은 Main 서버에, 사본은 Replica 서버에 저장하는 방식
- Replica 데이터베이스는 읽기 연산만을 지원 → 일반적으로 읽기 연산이 트래픽이 대다수이므로 Main 데이터베이스보다 수가 많아야 함
- Main/Replica 데이터베이스 둘 다 정상인 경우 역할이 나뉘어져 있지만, 한 측의 데이터베이스가 사용 불가능하다면 다른 측의 데이터베이스가 다 커버하도록 설계 됨

**장점**

1. 성능 : 읽기는 Replica, CUD 연산은 Main으로 분리되기 때문에 병렬로 처리도리 수 있는 query가 늘어남
2. 안정성 : 여러 DB 서버를 물리적으로 나누어두기 때문에 자연 재해 등으로 부터 데이터를 안정적으로 보존
3. 가용성 : DB 서버 일부에 장애가 발생해도, 다중화를 통한 데이터 동기화가 이루어져 계속 서비스 가능

![image](https://github.com/jun108059/til/assets/42997924/14e9458b-588b-4daa-a760-7ed89beb5025)

웹 계층과 데이터 계층에서 트래픽이 증가해도 확장가능하고, 고가용성과 내결함성을 보장할 수 있게 되었다!

> 이제 응답 시간과 성능을 개선하기 위해 캐시와 CDN에 대해 알아보자
## 4. 캐시

**기존 설계의 문제점**

- 애플리케이션의 성능은 데이터베이스를 얼마나 자주 호출하느냐에 크게 좌우된다.
- 지금 설계는 데이터베이스 조회가 필요한 요청이 올때마다 DB 호출이 이루어진다.
- DB 호출을 줄여서 성능을 개선해야한다.

> 캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두어서, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소
![image](https://github.com/jun108059/til/assets/42997924/d2b4c0ae-f875-4c0d-8537-92b520be9876)

가장 많이 활용되는 읽기 주도형 캐시 전략(read-through caching strategy)

0 comments on commit fa92025

Please sign in to comment.