서재

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

kiseoky 2024. 3. 28. 19:39

가상 면접 사례로 배우는 대규모 시스템 설계 기초 1장 내용을 정리한 글입니다.

개요

한 명의 사용자를 지원하는 시스템에서 출발하여 단계적으로 몇 백만 사용자를 지원하는 시스템을 설계한다.

단일 서버

  • 모든 컴포넌트가 단 한 대의 서버에서 실행되는 간단한 시스템
  • 웹 앱, 데이터베이스, 캐시 등이 전부 한대에서 실행된다.
  • 사용자의 요청은 DNS를 통해 ip 주소를 얻어낸 후 전달된다.

데이터베이스 분리

  • 웹 서버 계층과 데이터베이스 서버 계층을 독립적으로 확장할 수 있게 된다.

수직적 확장(Scale Up) vs 수평적 확장(Scale Out)

  • 수직적 확장
    • CPU, RAM 등 서버 성능을 업그레이드 하는 것을 의미한다.
    • 서버 성능을 업그레이드하는 데에는 물리적, 비용적 한계가 있다.
    • 장애에 대한 복구, 다중화 방안이 없다.
  • 수평적 확장은 서버 개수를 추가하는 것이다.
    • 위의 수직적 확장의 단점들 때문에 수평적 확장이 대규모 어플리케이션에 적합하다.

로드밸런서

  • 수평적 확장을 통해 웹 서버를 여러 대 두게 되면, 각 서버에 대한 연결을 위해 로드 밸런서를 이용해야 한다.
  • 서버 1이 다운되면 모든 트래픽은 서버2로 전송된다.
  • ASG(Auto Scaling Group) 등을 이용해 트래픽에 유연하게 대비할 수 있다.

출처 나

데이터베이스 다중화

출처 나

  • 웹 서버가 아닌 데이터베이스 서버에도 장애가 발생할 수 있다. 이를 해결하기 위해 데이터베이스를 다중화 한다.
  • master - slave 관계를 설정하고 원본은 master 서버, 사본은 slave 서버에 저장한다.
  • 쓰기 연산은 master 에서만 지원하고 slave는 읽기 연산만 지원한다.
    • 대부분의 애플리케이션은 읽기 연산의 비중이 훨씬 높기 때문이다.
  • 성능, 안정성, 가용성을 챙길 수 있다.
  • 가용성
    • 만약 한 대뿐인 slave 서버에 장애가 발생한다면, 일시적으로 모든 연산을 master 서버에서 처리하고 새로운 slave 서버를 생성하여 장애가 발생한 서버를 대체한다.
    • 만약 master 서버에 장애가 발생한다면, 한 대의 slave 서버가 master 가 되고, 새로운 slave 서버를 추가한다.
      • slave 데이터 서버에 저장된 데이터가 최신이 아닐 수 있다.
        • 복구 script를 돌려 추가해주어야 한다.
        • 다중 마스터, 원형 다중화 방식을 고려할 수도 있다.

캐시

  • 값 비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청을 보다 빨리 처리하기 위한 저장소
  • 별도의 캐시 계층을 두면 규모를 독립적으로 확장할 수 있다.
  • 읽기 주도형 캐시 전략
    • 값이 캐시에 있으면 캐시에서 반환
    • 없으면 DB에서 읽어서 캐시에 쓰고 반환
  • 유의점
    • 휘발성 메모리임에 유의해야 한다.
    • 만료 정책을 마련해야 한다. 너무 짧으면 miss가 많아지고, 길면 원본과 차이가 날 수 있다.
    • 일관성 유지
    • Single Point of Failure에 대비해 캐시 서버를 분산해야 한다.
      • 경우에 따라 Redis 실패 시 -> local 메모리 캐시 사용도 괜찮은 것 같다.
  • 캐시 메모리 과할당
    • 캐시 메모리가 너무 작아 성능이 떨어지는 경우나 데이터가 갑자기 늘어날 경우에 대비하여 메모리를 과할당할 수 있다.
  • 캐시 데이터 방출 정책
    • 메모리가 꽉 찼을 때 내보낼 데이터를 정하는 정책
    • LRU, LFU, FIFO 등

CDN

  • 정적 컨텐츠 제공
  • 지리적으로 가장 가까운 CDN 서버가 정적 컨텐츠를 제공한다.
  • 보통 Third-party 제공자에 의해 운영되므로 이에 대한 비용이 발생한다.
  • CDN 장애 시 동작 시나리오를 마련해두어야 한다.
    • 일시적으로 원본 서버에서 정적 컨텐츠를 가져와 제공

Stateless 웹 계층

  • 웹 계층을 수평적으로 확장하기 위해서는 상태 정보를 제거해야 한다.
  • NoSQL이나 관계형 데이터베이스 같은 지속성 저장소에 상태 정보를 저장하면 좋다.

데이터 센터

  • 여러 개의 데이터 센터를 이용하는 사례이다.
  • 장애가 없는 경우 GeoDNS(지리적 라우팅)을 이용해 가장 가까운 데이터 센터로 라우팅 된다.
  • 데이터 동기화 문제

메시지 큐

  • 메시지의 무손실을 보장하고, 비동기 통신을 지원하는 컴포넌트다.
  • 메시지 큐를 사용하면 서비스 또는 서버 간 결합이 느슨해져 안정적인 확장이 가능하다.
    • 생산자는 소비자에 장애가 발생해도 메시지를 발행할 수 있다.
    • 소비자는 생산자에 장애가 발생해도 메시지를 수신할 수 있다.

로그, 메트릭과 자동화

  • 사업 규모가 커지고 나면, 이런 도구들에 필수적으로 투자해야 한다.
  • 로그
    • 시스템의 오류와 문제를 쉽게 찾으려면 에러 로그를 모니터링 해야 한다.
  • 메트릭
    • 사업 현황에 유용한 정보를 얻을 수 있다.
      • daily active user, 재방문, 성능 모니터링
  • 자동화
    • 생산성을 높이기 위한 도구 활용
    • CI, CD 등

데이터 베이스 규모 확장

  • 수직적 확장
    • 고성능 자원 증설
    • 스택 오버플로우는 2013년 한 해 천만명의 사용자를 한 대의 마스터 사용했다고 한다.
    • 증설 한계, 비용, Single Point of Failure
  • 수평적 확장
    • 샤딩
      • 데이터 베이스를 샤드(shard)라고 부르는 작은 단위로 분할하는 기술이다.
  • 샤딩 시 고려할 사항
    • 데이터의 재 샤딩(resharding)
      1. 데이터가 너무 많아져서 하나의 샤드가 데이터를 더 이상 감당하기 힘들 때
      2. 샤드 간 분포가 균등하지 못하여 공간 소모가 불균형하게 일어날 때
      • 5장에서 배울 안정 해시를 이용해 해결한다.
    • 셀럽 문제
      • 특정 샤드에 쿼리가 집중되어 서버에 과부하가 생기는 문제
      • 저스틴 비버, 레이디 가가 등 셀럽의 정보가 담긴 샤드에 쿼리가 집중될 수 있음
    • 조인과 비정규화 문제
      • 샤드 적용 시 여러 샤드에 걸친 데이터를 조인하기 힘들어진다.
      • 비정규화를 통해 조인 없이 쿼리가 수행될 수 있도록 할 수 있다.
  • NoSQL의 다양한 활용 사례 참조