📗 개발자 책 읽기/가상 면접 사례로 배우는 대규모 시스템 설계 기초

[System Design Interview] 01. 사용자 수에 따른 규모 확장성 - 인프라 확장

민돌v 2022. 12. 19. 20:45
가상 면접 사례로 배우는 대규모 시스템 설계 기초 (System Design Interview) - 저 : 알렉스 쉬, 역 : 이병준 을 읽고 정리한 글입니다.

 

1장에서는 사용자 수에 따른 서비스 규모의 확장 흐름에 대해서 이야기합니다.

  • 단일서버부터 시작하여, 디비 분리, 서버 분리,  물리적인 데이터센터의 분리 등
  • 서비스 규모가 어떤식으로 확장되는지 큰 흐름을 파악할 수 있는 장이였습니다.

 

➡️ 사용자 수에 따른 적절한 시스템을 설계하기!

 

[목차]

  1. 단일서버 구성
  2. 데이터베이스의 분리
  3. 수직적 규모확장 vs 수평적 규모확장
  4. 캐시
  5. CDN 
  6. 무상태 웹 계층 (Stateless)
  7. 데이터 센터
  8. 메시지 큐 
  9. 데이터베이스의 규모 확장 (샤딩과 파티셔닝)

 

1. 단일 서버

  • 복잡한 시스템을 설계하기전에 모든 컴포넌트가 단 한대에서 실행되는 단일서버를 설계해 보자
  • 웹 앱, 데이터베이스, 캐시 등이 전부 한 대에서 실행하는 시스템을 보면서 클라이언트가 요청을 보낼 때부터 응답을 받을 때 까지의 과정을 살펴보자

 

단일서버 예시

👏🏻 흔히 면접에서 물어보는 "google.com, naver.com 을 주소창에서 검색할 때 일어나는 일" 을 간략하게 설명하는 것 과 같습니다. 

 

  1. 사용자는 도메인 이름(api.mysite.com)을 이용하여 웹사이트에 접속한다.
    • 이 접속을 위해서는 도메인 이름을 도메인 이름 서비스(DNS)에 질의하여 IP 주소로 변환하는 과정이 필요하다.
    • DNS 는 보통 제 3 사업자(third party) 가 제공하는 유료서비스이므로 우리 시스템(단일 서버)의 일부는 아니다.
  2. DNS 조회로 웹 서버의 IP 주소가 반환된다. (ex 15.123.23.123)
  3. 해당 IP 주소로 HTTP 요청이 전달된다.
  4. 요청을 받은 웹 서버는 HTML 페이지나 JSON 형태의 응답을 반환한다.

 


 

2. 데이터베이스 

  • 사용자가 늘면 서버 하나로는 충분하지 않아 여러 서버를 두어야 합니다.
    1. 하나는 웹/ 모바일 트래픽 처리 용도이고
    2. 다른 하는 데이터베이스용입니다.

➡️ 2 서버를 분리함으로써 그 각각을 독립적으로 확장해 나갈 수 있게됩니다.

 

데이터베이스는 크게 관계형 데이터베이스(RDBMS), 비-관계형 데이터베이스 (NoSQL) 2가지로 나눌 수 있다.

RDBMS 란

  • 관계형 데이터베이스 관리 시스템 (Relational DataBase Management System)
  • 자료를 테이블과 열, 칼럼으로 표현
  • SQL을 사용하면 여러 테이블에 있는 데이터를 그 관계에 따라 조인(join) 하여 합칠 수 있다.

NoSql 란

  • 비관계형 데이터베이스를 부르는 말
  • NoSql은 다시 4가지로 부류로 나눌 수 있다.
  • 키-값 저장소 (key-value store), 그래프 저장소 (graph store), 칼럼 저장소 (column store) , 문서 저장소(document store)
  • 비- 관계형 데이터베이스는 일반적으로는 조인 연산을 제공하지 않는다.

 

👏🏻 대체적으로는 RDBMS로 해결할 수 있고 최선일  것인데, 아래와 같은 경우에는 NoSQL이 적절한 선택일 수 있다. 

NoSql 이 유용한 상황

  • 아주 낮은 응답 지연시간이 요구됨
  • 다루는 데이터가 비정형이라 관계형 데이터가 아님
  • 데이터를 직렬화하거나 역직렬화할 수 있기만 하면 됨
  • 아주 많은 양의 데이터를 저장할 필요가 있음

 


 

3. 수직적 규모 확장 vs 수평적 규모 확장

수직적 규모 확장이란 (Scale-up)

  • 쉽게말해 서버, 컴퓨터, 저장소 등의 성능 및 크기를 늘리는 일 (물리적으로)
  • 단순하지만 무한대로 증설할 수 없다.
  • 한대의 서버가 다운될 경우 장애 대응을 할 수 없다는 치명적인 단점을 가지고 있다.
  • ✅ 따라서 대규모 애플리케이션을 지원하는 데는 수평적 규모 확장법이 보다 적절하다.

 

수평적 규모 확장이란 (Scale-out)

  • 더 많은 서버를 추가하여 성능을 개선하는 행위
  • 너무 많은 사용자(트래픽) 이 몰렸을 때, 서버를 증설하여 트래픽을 분산하는 방법이다.
  • 부하 분산기 or 로드 밸런서를 도입하는 방법이다.

 


1) 로드 밸런서 

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

 

로드밸런서 과정

로드밸런서가 동작하는 과정

사용자는 로드밸런서의 공개 IP 주소 (Public IP)로 접속한다.

  • 따라서 웹 사버는 클라이언트의 접속을 직접 처리하지 않는다.
  • 더 나아가서 서버 간 통신에는 사설 IP (Private IP)가 이용된다.

 

로드밸런서가 장애를 대응하는 과정

위처럼 스케일 아웃을 통해서 서버를 여러 대로 늘리게 되면 장애를 자동복구하지 못하는 문제 (no failover)도 해소할 수 있고, 웹 계층의 가용성은 향상된다.
  1. 서버 1이 다운되면 모든 트래픽이 서버 2로 전송된다.
    • 따라서 전체 웹사이트가 다운되는 일이 방지된다.
    • 부하를 나누기 위해 새로운 서버를 추가할 수 도 있다.
  2. 웹사이트로 유입되는 트래픽이 가파르게 증가하면 두 대의 서버로 트래픽을 감당할 수 없는 시점이 오는데, 로드밸런서가 있으므로 우아하게 대처할 수 있다.
  3. 웹 서버 계층에 더 많은 서버를 추가하기만 하면 된다.
  4. 그러면 로드밸런스가 자동적을 트래픽을 분산 처리한다.

 


2) 데이터베이스 다중화

DB Replication 이라고도 한다.
  • 데이터베이스를 Master(주)-Slave(부)로 나누는데 쓰기 연산은 Master에서만 지원하고, 읽기 연산은 Slave에서만 지원한다.
  • 대부분의 애플리케이션에서는 쓰기 작업 보다는 읽기 작업이 훨씬 많기 때문에 Slave 데이터베이스가 훨씬 많다.

 

디비 다중화 예시

데이터베이스 다중화의 장점

  • 더 나은 성능 
    • 모든 데이터 변경 연산은 Master 서버로만 전달되는 반면 읽기 연산은 Slave 데이터베이스 서버들로 분산된다.
    • 병렬로 처리될 수 있는 쿼리의 수가 늘어나므로 성능이 좋아진다.
  • 안전성
    • 데이터베이스 서버 가운데 일부가 파괴되어도 데이터는 보존될 것이다.
    • 데이터를 지역적으로 떨어진 여러 장소에 다중화 시켜놓을 수 있기 때문이다.
  • 가용성
    • 데이터를 여러 지역에 복제해 둠으로써, 하나의 데이터베이스 서버에 장애가 발생하더라도 다른 서버에 있는 데이터를 가져와 계속 서비스할 수 있게 된다.

 

로드밸런서와 데이터베이스 다중화를 고려한 시스템 설계안

  1. 사용자는 DNS로부터 로드밸런서의 공개 IP 주소를 받는다.
  2. 사용자는 해당 IP 주소를 사용해 로드밸런서에 접속한다.
  3. HTTP 요청은 서버 1이나 서버 2로 전송된다.
  4. 웹 서버는 사용자의 데이터를 부 데이터베이스 서버에서 읽는다.
  5. 웹 서버는 데이터 변경 연산은 주 데이터베이스로 전달한다.

로드밸런서와 디비 다중화를 적용한 시스템

 

 


 

4. 캐시 (Cache)

캐시는 응답시간을 개선하는 방법이다.
응답시간을 개선하기 위해서는 캐시를 붙이고 정적 콘텐츠를 콘텐츠 전송 네트워크 (CDN) 으로 옮기면 개선할 수 있다.

👏🏻 어플리케이션의 성능은 데이터베이스를 얼마나 자주 호출하느냐에 크게 좌우되는데, 캐시가 이 문제를 완화할 수 있다.

 

1) 캐시 계층

캐시 계층은 데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠르다.
  • 별도의 캐시 계층을 두면 데이터베이스의 부하를 줄일 수 있고, 독립적인 확장이 가능하다.

캐시계층의 요청 처리 과정

  1. 요청을 받은 웹 서버는 캐시에 응답이 저장되어 있는지를 확인한다.
  2. 만일 저장되어 있다면 해당 데이터를 클라이언트에 반환한다.
  3. 없는 경우에는 데이터베이스 쿼리를 통해 데이터를 찾아 캐시에 저장한 뒤 클라이언트에 반환한다.

 

캐시 사용 시 유의할 점

  1. 캐시는 갱신은 자주 일어나지 않지만 참조는 빈번하게 일어난다면 고려해볼만 하다.
  2. 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않다.
    • 캐시는 데이터를 휘발성 메모리에 두기 때문에, 캐시 서버가 재시작되면 모든 데이터는 사라진다.
  3. 만료된 데이터는 캐시에서 삭제되어야 한다.
    • 만료 기한에 대한 정책을 마련하는 것이 좋다.
    • 만료 기한이 너무 짧으면, 데이터베이스를 너무 자주 읽게 되며, 너무 길면 원본과 차이가 날 가능성이 높아진다.
  4. 데이터 저장소의 원본과 캐시 내의 사본 일관성을 확인해야 한다.
  5. 캐시 서버를 한 대만 두는 경우 해당 서버는 단일 장애 지점(SPOF)이 되어 버릴 수 있다.
  6. 캐시 메모리 크기는 너무 크지도 작지도 않게 적절하게 잡아야 한다.
  7. 캐시가 꽉 차버리면 LRU, LFU, FIFO 같은 데이터 방출 정책들을 사용해서 기존 데이터를 내보내야 한다.

 


 

5. 콘텐츠 전송 네트워크 - CDN 

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

정적 파일들 (front 파일들) 을 정적인 저장소에 지리적으로 분산하여, 두는 방법이다.

자세한 내용은 이전 블로그 정리 글에서! [AWS] CloudFront CDN서비스를 이용해서 Front 구성하기

 


 

6. 무상태 웹 계층 (stateless)

사용자의 상태 정보를 웹 계층에서 제거하여 웹 계층을 수평적으로 확장하는 방법이다.

 

http 프로토콜이 무상태성 특징을 가집니다.

이것에 대해 궁금하시다면 책의 내용보다는 rest api 에 대해서 공부해 보시는 걸 추천드립니다.
[Restful api 란] - 진짜 Rest API 란 무엇이고 어떻게 써야하는 걸까?

 

무상태 아키텍쳐

 


 

7.  데이터센터 

  • 여러분의 웹사이트가 엄청나게 성장하여 전 세계적으로 사용자가 증가한다면 데이터센터는 필수입니다.
  • 장애가 없는 상황에서 사용자는 가장 가까운 데이터 센터로 안내되는데, 통상 이 절차를 지리적 라우팅이라고 부릅니다.
  • 만약 데이터 센터 중 하나에 심각한 자애가 발생하면 모든 트래픽은 장애가 없는 데이터 센터로 전송된다.
    • 22.10.15 카카오 데이터센터에서 화재가 나 2일간 카카오톡 서비스가 장애가 난 대규모 사태가 있었죠 ㄷㄷ (잡담임다)

 

두 개의 데이터센터를 이용하는 사례

 

다중 데이터센터 아키텍쳐를 만들기위한 기술적 난제 

  1. 트래픽 우회
    • 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야 합니다.
  2. 데이터 동기화
    • 데이터 센터마다 별도의 데이터베이스를 다중화하기
  3. 테스트와 배포
    • 여러 위치에서 애플리케이션을 테스트 해보고, 자동화 배포가 모든 데이터 센터에 동일하게 설치되도록 하는 것이 중요합니다.

 


 

8. 메시지 큐

  • ✨ 메시지 큐는 메세지의 무손실(메시지 큐에 일단 보관된 메시지는 소비자가 꺼낼 때 까지는 안전하다.) 을 보장하는 비동기 통신을 지원하는 컴포넌트 입니다.

 

메세지 큐 기본 아키텍쳐 (과정)

  1. 생성자 (Publish/Producer) 는 메세지 큐에 발행한다.
  2. 큐에는 보통 소비자 (Consumer/Subscribe) 가 메세지를 꺼내서 동작을 수행한다.

메세지 큐

 

메세지 큐의 장점

메시지 큐를 이용하면 시븟 또는 서버 간 결합이 느슨해져서, 규모 확장성이 보장되어야 하는 안정적 어플리케이션을 구성하기 좋습니다.
  • 생산자는 소비자 프로세스가 다운되더라도 메시지를 발행할 수 있음
  • 소비자는 생산자 서비스가 가용가능한 상태가 아니더라도 메시지를 수신할 수 있음
  • 시간이 매우 오래걸리는 사진 보정같은 작업들이 비동기적으로 처리되는 메시지큐 작업의 좋은 예시입니다.

 


 

9. 데이터베이스의 규모 확장 (샤딩)

저장할 데이터가 많아지면 데이터베이스에 대한 부하도 증가한다. 이 때도 애플리케이션 서버처럼 스케일 업, 스케일 아웃 두 가지 방법이 존재한다.

데이터베이스 규모 증설


 

✨ 1) 샤딩

  • 데이터베이스의 수평적 확장을 위한 방법입니다.
  • 샤딩은 대규모 데이터베이스를 샤드(shard) 라고 부르는 작은 단위로 분할하는 기술을 말합니다.
  • 샤딩 전략을 구현할 때 중요한 것은 샤딩 키 이고, 샤딩 키에 따라서 한 곳으로만 부하가 집중될 수 있고 여러 곳으로 적절히 잘 분산될 수도 있다.

 

샤딩을 위해서 고려해야 할 조건

  1. 데이터의 재 샤딩
    • 데이터가 너무 많아져서 하나의 샤드로는 더 이상 감당하기 어려울 때
    • 샤드 간 데이터 분포가 균등하지 못하여 어떤 샤드에 할당된 공간 소모가 다른 샤드에 비해 빨리 진행될 때
  2. 유명 인사
    • 핫스팟 키 문제라고도 부르는데, 특정 샤드에 쿼리가 집중되어 서버에 과부하가 걸리는 문제
  3. 조인과 비정규화
    • 일단 하나의 데이터베이스를 여러 샤드 서버로 쪼개고 나면, 여러 샤드에 걸친 데이터를 조인하기가 힘들어진다.
    • 이를 해결하는 한 가지 방법은 데이터베이스를 비정규화하여 하나의 테이블에서 쿼리가 수행될 수 있도록 하는 것이다.

 

데이터베이스 샤딩을 적용한 서비스 아키텍쳐 예시

 

 

🤔 샤딩과 파티셔닝의 차이점

  • 파티셔닝이란 퍼포먼스(performance), 가용성(availability) 또는 정비용이성(maintainability)를 목적으로 당신의 논리적인 데이터 엘리먼트들을 다수의 엔티티(table)로 쪼개는 행위를 뜻하는 일반적인 용어이다.
  • 샤딩은 수평 파티셔닝(horizontal partitioning)과 동일하다.
    • 데이터베이스를 샤딩하게 되면 기존에 하나로 구성될 스키마를 다수의 복제본으로 구성하고 각각의 샤드에 어떤 데이터가 저장될지를 샤드키를 기준으로 분리한다.
    • 예를 들면, 나는 고객의 데이터베이스를 CustomerId를 샤드키로 사용하여 샤딩하기로 하였다. 0 ~ 10000 번 고객의 정보는 하나의 샤드에 저장하고 10001 ~ 20000 번 고객의 정보는 다른 샤드에 저장하기로 하였다. DBA는 데이터 엑세스 패턴과 저장 공간 이슈(로드의 적절한 분산 , 데이터의 균등한 저장)를 고려하여 적절한 샤드키를 결정하게 된다.
  • 수직 파티셔닝(vertical partitioning)은 하나의 엔티티에 저장된 데이터들을 다수의 엔티티들로 분리하는것을 말한다.
    • (마찬가지로 공간이나 퍼포먼스의 이유로) 예를 들면, 한 고객은 하나의 청구 주소를 가지고 있을 수 있다.
    • 그러나 나는 데이터의 유연성을 위해 다른 데이터베이스로 정보를 이동하거나 보안의 이슈등을 이유로 CustomerId를 참조하도록 하고 청구 주소 정보를 다른 테이블로 분리할 수 있다.
  • 요약하면 파티셔닝은 퍼포먼스, 가용성, 정비용이성등의 목적을 위해 논리적인 엔티티들을 다른 물리적인 엔티티들로 나누는것을 의미하는 일반적인 용어이다.
    • 📌 수평 파티셔닝 또는 샤딩은 스키마 복제 후 샤드키를 기준으로 데이터를 나누는것을 말한다.
    • 📌 수직 파티셔닝은 스키마를 나누고 데이터가 따라 옮겨가는것을 말한다.

 

 

끝!!

 

 

가상 면접 사례로 배우는 대규모 시스템 설계 기초

 


참고