# 사용자 수에 따른 규모 확장성

### 데이터베이스

- **RDBMS** : 자료를 테이블과 [행](https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=netrance&logNo=110151734823#:~:text=017%252D5555%252D5555-,%25ED%2596%2589%2520(row),-%25ED%2596%2589%25EC%259D%25B4%25EB%259E%2580%252C%2520%25ED%2585%258C%25EC%259D%25B4%25EB%25B8%2594%25EC%2597%2590%25EC%2584%259C%2520%25EA%25B0%2580%25EB%25A1%259C)(레코드)과 열로 표현. Join이 가능하다.

- **NoSQL** : RDBMS가 아닌 데이터베이스. Key-value, graph, column, document로 나눈다.

### Scale up & scale out

- **Scale up** : 성능을 좋게. 다만 성능 향상에는 한계가 있고, SPOF가 된다.

- **Scale out** : 쪽수를 많게. 다만 트래픽을 여러 서버에 분산해줘야 한다.

### 로드밸런서(LB)

- **Load Balancing** : 트래픽을 서버로 적절히 분산한다.

- **Forward proxy **: 서버의 IP를 숨기고 LB의 IP만 노출한다. 반대 개념은 reversed porxy

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

- **성능(performance)** : 읽기 연산을 분산해서 처리하기 때문에 성능 증가

- **가용성(availability) **: 장애가 생겨도 다른 DB로 대체 가능

- **안정성(reliability)** : DB 하나가 훼손되어도 원본 유지 가능

### 캐시

서버가 DB에서 같은 값을 두 번 읽으면 낭비기 때문에 중간에 캐시를 둬서 DB 질의의 결과를 임시 저장한다. 서버는 질의할 때 캐시를 먼저 살피고 값이 없으면(miss) DB에서 가져온다. 이 [캐시 전략](https://codeahoy.com/2017/08/11/caching-strategies-and-how-to-choose-the-right-one)을 **읽기 주도형 캐시**라고 부른다.

- 쓰기보다 읽기 연산이 많을 때 유리하다.

- 오래 저장되지 않을 자료에 유리하다.

- 적절한 시간이 지나면 값을 지워야 한다. 성능 문제(↓) vs 일관성 문제(↑)

- 캐시와 DB의 값이 동일하다는 것을 보장해야 한다. 일관성 문제

- 캐시를 한 대만 두면 SPOF가 되기 때문에 다중화해야 한다.

- 캐시 크기를 정해야 한다. 너무 작으면 값이 자주 방출돼서 성능이 떨어진다.

- 데이터 방출 정책을 정해야 한다. 주로 [LRU](https:///4eb5ed6a47414a7da948468adca6936a#74e5eef579cd4fc5938a342ba3fa8c76)를 쓰고 LFU, FIFO를 쓰기도 한다.

### 콘텐츠 전송 네트워크(CDN)

정적 콘텐츠를 지리적으로 분산된 서버에 저장해놓고 가장 가까운 서버에서 값을 가져오는 방식이다. 탱커랄까

- **돈 걱정** : 트래픽에 따라 돈을 내기 때문에 꼭 필요한 것만

- **장애 대처** : CDN이 죽으면…? 

- **만료 시한 설정 **: 캐시랑 똑같이 적절할 때 갱신해야 한다.

- **무효화** : 아직 만료 안되었는데 강제로 만료시키기

    - CDN 서비스 사업자가 제공하는 API

    - 같은 콘텐츠라도 버전을 바꾼다.

### 무상태 웹 계층

로드밸런싱이 만든 작은 문제, 서버는 A,B가 있다.

1. A 서버에서 장바구니에 물건을 하나 담았다.

2. 그런 다음 B 서버에서 다른 상품도 담았는데

3. A 서버에서 담은 물건이 장바구니에 없다…!

4. 왜냐하면 A 서버와 B 서버는 서로 소통을 안하기 때문

이에 대한 해결책은 크게 두 가지가 있다.

- **Sticky session** : A, B 서버 왔다갔다 하지 말고 유저 한 명은 한 서버가 전담하도록 한다. LB에 무리간다.

- **공유 저장소** : A, B 서버가 모두 참조할 수 있는 아주 가벼운 데이터베이스를 둔다. 여기다가 장바구니 물건을 담아둔다.

공유 저장소는 빨라야 하기 때문에 NoSQL로 주로 만든다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134309_ldegHF4xQW43WFQlhN?q=80&s=1280x180&t=outside&f=webp)

### 데이터 센터

내 서버가 있는 서울에 지진이 나면?? 서비스가 안된다. 이 문제를 해결하기 위해서 도쿄에도 같은 서비스를 운영한다. 그러면 한 쪽이 멈춰도(failover) 다른 한 군데에서 서비스를 하면 되기 때문에 안전하다.

- **트래픽 우회** : 적절하게 트래픽을 보내야 한다. (GeoDNS)

- **데이터 동기화** : 서울에 있는 DB가 멈추면 데이터 복구가 안된다.

- **배포** : 배포를 할 때 서울과 도쿄가 동일한 어플리케이션을 설치하도록 해야 한다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134310_VrF3tpcrdjdCXUuVd0?q=80&s=1280x180&t=outside&f=webp)

### 메시지 큐

메시지 큐는 메시지의 무손실을 보장하는 비동기 통신 컴포넌트이다. 생산자와 소비자를 분리해서 확장하기도 좋고 안정적이게 된다. 

### 로그, 메트릭 그리고 자동화

- **로그** : 여러 서버의 에러 로그를 한군데 모으면 검색, 조회가 좋다.

- **메트릭** : 사업에 대한 인사이트를 얻고, 시스템의 현재 상태를 파악한다.

    - **호스트 단위 메트릭** : CPU, 메모리, 디스크 I/O

    - **종합 메트릭** : DB 계층의 성능, 캐시 계층의 성능

    - **핵심 비즈니스 메트릭** : 일일 능동 사용자(DAU), 수익, 재방문

- **자동화** : 빌드, 테스트 배포 등의 절차를 자동화한다. CI/CD

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134311_Rj31zoLIE8Tb55bXdy?q=80&s=1280x180&t=outside&f=webp)

### 데이터베이스의 규모 확장

**수직적 확장**

서버 성능을 키운다. 서버 하드웨어에는 한계가 있고 SPOF의 위험이 있다. 또 비싸다.

**수평적 확장**

서버를 늘린다. 대규모 데이터베이스를 샤드(shard)로 나누고 데이터를 여러 대의 서버에 분산해서 저장한다. 어느 서버에 넣을지는 각 데이터의 샤딩 키(혹은 파티션 키)를 통해 결정한다. 

- **재샤딩** : 한 샤드가 다른 샤드들에 비해 빨리 소진되면서 감당하기 어려울 때, 샤딩 키를 다시 분배해서 저장해야 하는 문제가 발생한다.

- **셀럽 문제** : 특정 샤드에 질의가 집중돼서 과부화가 걸리는 문제

- **조인과 비정규화** : 조인이 힘들기 때문에 비정규화를 수행할 수 밖에 없다.

For the site tree, see the [root Markdown](https://slashpage.com/kaonmir.md).
