5 분 소요

이 포스트는 현재 작성중입니다.
미완성된 내용이나 코드가 존재하므로 유의하시기 바랍니다.

시스템 디자인 면접 (System Design Interview) : 시스템 아키텍처를 설계하는 면접

  • 질문 범위도 매우 크고 모호하며, 답변 절차 또한 정형화되어 있지 않음
    • 시스템에 따른 변이 (variation)이 많음
      • 의사소통 및 문제 해결 능력이 소프트웨어 엔지니어의 필요 능력과 비슷함
      • 지원자들은 그 모호한 문제를 어떻게 분석하고 단계적으로 해결하는지를 확인
        • 문제 해결 아이디어를 어떻게 설명하고 토론하는지?
        • 문제 해결 아이디어를 어떻게 평가하고 개선하는지?

사용자 수에 따른 규모 확장성 : 사용자가 얼마나 되는지에 따라 변화하는 시스템 설계

단일 서버 : 모든 컴포넌트가 단 한 대의 서버에서 실행되는 시스템을 설계

  • 웹, 어플리케이션, 데이터베이스, 캐시 모두가 하나의 서버에서 실행

단일 서버에서 사용자의 요청이 처리되는 과정

  1. 사용자는 도메인 네임을 이용해 웹 사이트에 접속한다.
    1. 도메인 네임을 DNS (Domain Name Service)에 질의한다.
    2. DNS 조회 결과로 IP 주소 (웹 서버의 주소)가 반환된다.
  2. 해당 IP 주소로 HTTP 요청이 전달된다.
  3. 요청을 받은 웹 서버는 HTML 페이지나 JSON 형태의 응답을 반환한다.
  • 그렇다면 실제 요청은 어디에서 오는가?
    1. 웹 어플리케이션인 경우?
      1. 비즈니스 로직의 구현과 데이터 저장의 처리를 위한 서버 구현
      2. 사용자에게 표현하기 위한 클라이언트 구현
    2. 모바일 앱인 경우?
      1. 모바일 앱과 웹 서버 간의 통신에는 HTTP 프로토콜을 이용
      2. HTTP 프로토콜을 통해 반환될 응답 데이터의 포맷으로 JSON을 사용

데이터베이스 서버 : 트래픽을 처리할 서버 (웹 계층)에 DB 서버 (데이터 계층)을 증설

  • 어떤 데이터베이스를 사용할 것인가?
    1. 관계형 데이터베이스를 선택할 경우?
      • 관계형 데이터베이스 관리 시스템 (RDBMS) : MySQL, …
      • 자료를 테이블, 열, 칼럼으로 표현
      • 여러 테이블에 있는 데이터를 그 관계에 따라 조인 (join)
    2. 비관계형 데이터베이스 (NoSQL)를 선택할 경우?
      • 저장소 : 키-값 (key-value), 그래프 (graph), 칼럼 (column), 문서 (document)
    3. 비관계형 데이터베이스가 최선인 경우는 언제?
      • 아주 낮은 지연 시간 (latency)이 요구됨
      • 다루는 데이터가 비정형 (unstructured) 데이터임
      • JSON 등 데이터를 직렬화 (serialize)하거나 역직렬화할 수 있기만 하면 됨
      • 아주 많은 양의 데이터를 저장해야 함

수직적 규모 확장 vs 수평적 규모 확장?

  • 수직적 확장 (scale-up) : 서버에 고사양 자원을 추가
    • 서버로 유입되는 트래픽의 양이 적을 때 최선
    • 단순하지만, 한계가 명확함 : 하나의 서버에 CPU나 메모리를 무한대로 증설할 수 없음
    • 장애에 대한 자동 복구 (failover)이나 다중화 (re-dundancy) 방안을 제시하지 않음
      • 서버에 장애가 발생하면, 어플리케이션이 그대로 중단된다.
  • 수평적 확장 (scale-out) : 더 많은 서버를 추가하여 성능을 개선
    • 로드밸런서 (Load balancer) : 부하 분산 집합 내의 웹 서버들에게 트래픽 부하를 분산
      • 로드밸런서의 공개 IP로 접속 : 웹 서버가 클라이언트의 접속을 직접 처리하지 않음
      • 같은 네트워크 내의 서버 간 통신에는 사설 IP 주소 사용
      • 장애를 자동으로 복구하지 못하는 문제 (no failover) 해소
        • 서버 a가 오프라인으로 상태가 변경되어도 모든 트래픽이 서버 b로 전송
      • 웹 계층의 가용성 (availability) 향상
        • 로드밸런서를 통해 트래픽을 자동적으로 분산 가능
    • 데이터베이스 다중화 : 원본은 master 서버에, 사본은 slave 서버에 저장
      • 쓰기 연산 (write)과 DB를 변경하는 명령어의 입력은 master 서버에서만 가능
      • slave 서버는 master 서버에서 사본을 전달받아, 읽기 연산 (read)만을 지원
        • 성능 향상 : 다중화 모델을 통해 병렬로 처리될 수 있는 질의 (query)의 수 증가
        • 안정성 (reliability) : 다중화된 DB를 여러 곳에 분산 가능
        • 가용성 (availability) : 어떤 DB 서버에 장애가 발생해도 서비스 지속 가능
      • DB 서버 하나가 오프라인 상태가 된다면?
        • 1대뿐인 slave 서버가 오프라인 상태인 경우?
          • 읽기 연산이 한시적으로 모두 master 서버로 전달
        • 여러 대의 slave 서버 중 하나가 오프라인 상태인 경우?
          • 읽기 연산이 나머지 slave 서버로 분산
        • 1대뿐인 slave 서버를 가진 master 서버가 오프라인 상태인 경우?
          • 해당 slave 서버가 master 서버가 돠어 모든 DB 연산 수행
          • 프로덕션 (production) 환경 : slave 서버의 데이터가 최신이 아닐 수도 있음
            • 복구 스크립트 (recovery script)를 통한 추가
  • 로드밸런서와 데이터베이스 다중화를 고려한 설계
    • 사용자는 DNS로부터 로드밸런서의 공개 IP 주소를 받는다.
    • 사용자는 해당 IP 주소를 사용해 로드밸런서에 접속한다.
    • HTTP 요청은 서버 1이나 서버 2로 전달된다.
    • 웹 서버는 사용자의 데이터를 slave 데이터베이스에서 읽는다.
    • 웹 서버는 데이터 변경 연산을 master 데이터베이스로 전달한다.

캐시 (Cache) : 응답 시간 (latency) 개선을 위해 데이터를 잠시 보관

  • 캐시 계층 : 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 보관
    • 주도형 캐시 전략 (read-through caching strategy)
      1. 만약 데이터가 캐시에 있다면, 캐시에서 데이터를 읽음
        • 데이터가 캐시에 없다면, DB에서 해당 데이터를 읽어 캐시에 씀
      2. 캐시에서 웹 서버로 데이터를 반환함
  • 캐시를 사용할 때 고려해야 할 점?
    • 캐시는 어떤 상황에 바람직한가? : 갱신이 드물지만, 참조가 빈번한 데이터
    • 어떤 데이터를 캐시에 저장? : 영속적이지 않은 데이터
    • 캐시 내의 데이터는 어떻게 만료 (expire)할까? : 캐시에서 정책에 따라 삭제
    • 일관성 (consistency)는 어떻게 유지할까? : 원본 갱신 연산과 캐시 갱신 연산이 단일 트랜잭션으로 처리되어야
    • 장애에는 어떻게 대처할까? : 단일 장애 지점의 발생을 피해 캐시 서버를 분산
    • 캐시 메모리의 크기는? : 캐시 메모리를 과할당 (over-provision)
    • 데이터 방출 (eviction) 정책은? : LRU, LFU 등을 경우에 맞게 적용

컨텐츠 전송 네트워크 (CDN) : 정적 컨텐츠의 전송에 쓰이는 분산 서버 네트워크

  • 정적 컨텐츠 (이미지, 비디오, CSS, JavaScript 파일 등)을 캐시
  • 사용자가 웹 사이트에 방문하면, 가장 가까운 CDN 서버가 정적 컨텐츠를 전달
  1. 사용자가 이미지 URL를 통해 image.png에 접근한다.
    • URL의 도메인은 CDN 서비스 사업자가 제공
  2. CDN 서버의 캐시에 해당 이미지가 없으면 원본 서버에서 파일을 요청
    • 원본 서버가 파일을 반환할 때, 응답 HTTP 헤더는 TTL 값을 포함
  3. CDN 서버는 파일을 캐시하고 사용자에 반환 (TTL 값만큼 캐시)
    • 사용자가 만료가 안된 이미지의 요청을 CDN 서버에 전송하면, 캐시로 처리
  • CDN 사용 시 고려할 사항?
    • 비용 : 자주 사용되지 않는 컨텐츠를 캐싱하는 것은 비효율적
    • 만료 기한 : time-sensitive한 컨텐츠의 만료 기한은 신중히 설정해야 함
    • CDN 장애 대처 방안 : CDN이 오프라인 상태일 때의 동작에 대한 고려
    • 컨텐츠 무효화 (Invalidation) 방법 : CDN 서비스 사업자가 제공하는 API를 이용한 컨텐츠 무효화
      • 컨텐츠의 다른 버전을 서비스하도록 오브젝트 버저닝 (object versioning) 이용
  • CDN과 캐시를 추가한 설계
    • 정적 컨텐츠는 웹 서버가 아닌 CDN을 통해 서비스됨
    • 캐시를 통해 데이터베이스의 부하가 줄어들 수 있음

무상태 (stateless) 웹 계층 : 웹 계층을 수평적으로 확장하는 방법

  • 사용자 세션 데이터와 같은 상태 정보를 웹 계층에서 제거해야 함
  • 상태 정보를 관계형 DBNoSQL과 같은 지속성 저장소에 보관하고 필요할 때 가져옴

상태 정보 의존적인 아키텍쳐 : 클라이언트 정보에 대한 상태를 유지하며 요청들 사이에 공유

  • 사용자 A의 상태 정보가 서버 1에 저장되면,
    • 해당 사용자 인증에 대한 HTTP 요청은 해당 서버로만 가야 한다.
    • 다른 서버로 가면 사용자 인증은 무조건 실패한다.
  • 같은 클라이언트로부터의 요청은 항상 같은 서버로만 전송된다.
    • 고정 세션 (sticky session) 기능을 지원하는 로드밸런서에 부담을 준다.
    • 로드밸런서 뒷단에 서버를 추가 및 제거가 어렵고, 서버의 장애 처리 또한 복잡해진다.

무상태 아키텍처 : 사용자로부터의 HTTP 요청은 어떤 웹 서버로도 전달 가능함

  • 웹 서버는 상태 정보가 필요할 때에 공유 저장소 (Shared Storage) 에서 데이터를 가져옴
    • 상태 정보는 웹 서버로부터 물리적으로 분리

Reference