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

요약

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

아키텍처 개념을 실제 설계 판단에 연결하기 위한 참고 노트입니다.

핵심 포인트

  • 가상 면접 사례로 배우는 대규모 시스템 설계 기초 리뷰
  • 가상 면접 사례로 배우는 대규모 시스템 설계 기초
    1. 개요
    1. 내용 정리
  • 1~3장 내용 정리

지식 그래프

정리 내용

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

학습 목적으로 정리한 내용으로 문제가 있다면 내리겠습니다.

(이 책은 한국어판 저작권은 에이전시 원을 통해 저작권자와의 독점 계약으로 인사이트에 있습니다. 저작권법에 의해 한국 내에서 보호를 받는 저작물이므로 무단전재와 무단 복제를 금합니다.)

0. 개요

이 책에서는 시스템 디자인과 관련된 문제를 설명하고 있다. 1~3 장까지는 확장성, 규모 측정, 면접 방법 등 기초적인 내용을 다루고 그 뒤는 특정 시스템에 대한 설계 방법을 다루고 있다.

  • 인프라나 백엔드 개발자가 읽으면 시스템을 볼 때 조금 더 구조를 파악하기 용이 할 듯 하다. 또한 이 책의 주된 목적은 사실 면접을 준비하기 위함일 듯 하다. 토스 NEXT 개발자 모집같은 경우 서술형 문제를 출제한다. 많은 후기에서 이 책이 도움이 됐다고 이야기하고 있다. 볼드나 색깔을 다르게 처리한 부분은 개인적으로 재미있거나 중요한거 같은 곳에 해놓았다.

1. 내용 정리

1~3장 내용 정리

  • 1장의 내용은 사용자 수에 따른 규모 확장성을 다루고 있다. 수직적 규모 확장(스케일 업)과 수평적 규모 확장(스케일 아웃)을 어떤 방식으로 하는 지, 부하를 줄이기 위해 캐시, 로드벨런스, CDN을 어떻게 사용하는지 그리고 무상태 아키텍처를 통해 분산 시스템에서 세션을 유지하기 위한 구조로 어떤 부분이 유리한지, 그리고 메시지 큐로 무손실을 어떻게 보장하는지 마지막으로 모니터링과 로깅 등 유지보수 정책을 설명한다.
    • 1장은 시스템을 확장할 때 생기는 문제점과 그 해결 방법을 광범위하게 다룬다. 대부분의 시스템에서 사용되는 기본적인 구조를 다루고 있다.
  • 2장의 내용은 규모를 측정하는 방식에 대해 설명하고 있다. 프로그래머가 알고있으면 좋은 응답지연 시간의 값과 가용성을 보장하는 수치들 그리고 저장소의 용량을 구하는 예시들을 설명하고 있다.
    • QPS, 저장소 요구량, 캐시 요구량, 서버 수 등을 구하는 방법에 대해 설명하고 있다. 어렵다.
  • 3장의 내용은 시스템 설계 면접 공략에 대해 알려주고 있다. 3장 이후 계속 적용될 설계의 4가지 단계에 대해 설명한다.
    • 1단계 문제 이해 및 요구 사항 분석
      • 이 단계에서는 면접관에게 많은 질문을 던져 요구사항을 명확히 해야한다. 또한 시스템 설계의 단순화를 위해 설계 범위를 줄여야한다. 이 부분에서 최대한 명확한 요구사항을 파악해야한다.
    • 2단계 개략적인 설계안 제시 및 동의 구하기
      • 대개 이런 면접의 경우 면접관과 소통하는 것이 중요하다고 이 책에서 밝히고 있다. 라이브 코딩 테스트도 동일하게 적용된다. 개략적인 설계를 하고 면접관에게 동의를 구하며 맞는 길로 가는지 확인하자.
    • 3단계 상세 설계
      • 개략적인 설계를 바탕으로 상세 설계를 하면된다. 가령 테이블 구조를 어떻게 생성하는지 또 요구사항을 분석하여 얼마만큼의 부하를 감당할 수 있는 시스템을 설계해야하는지 이런 상세한 내용을 추가하는 과정이다.
    • 4단계 마무리
      • 마무리는 면접관과 소통하면서 설계된 내용을 설명한다. 주요 컴포넌트의 짧고 명확하게 설명하고 추후 유지보수 방향성이나 확장성 또는 고려하면 좋을 거 같은 부분을 이야기하면 끝이다.

설계 예시 소개

  1. 처리율 제한 장치의 설계 처리율 제한 장치는 시스템 내부 트래픽의 부하를 제어하기 위한 장치로 “초당 게시글 제한” 과 같은 제한 장치를 미들웨어 또는 어플리케이션에 배치하는 장치이다.
  • 이 부분의 키포인트는 처리율 제한 알고리즘인거 같다.
    • 토큰 버킷
    • 누출 버킷
    • 고정 윈도 카운터
    • 이동 윈도 로그
    • 이동 윈도 카운터
  • 재미있는 부분은 OSI 7계층을 참고하여 다양한 계층에서 처리율을 제한할 수 있는 점이다.
  • 장치를 배치할 곳을 정하는 것도 재미있다. 미들웨어 형식 또는 어플리케이션 또는 클라이언트 등 위치에 따라 용도와 장단점이 존재한다.
  1. 안정 해시 설계 이 파트는 스케일 아웃 그리고 샤딩에서 꼭 필요한 안정 해시를 구하는 방법에 대해 설명한다. 안정해시란 데이터를 분산 저장소에 균등하게 보관하기 위한 기술이다.
  • 안정 해시는 해시 공간과 해시 링이라는 개념에서 시작된다. 예를 들어 SHA-1을 사용한다 가정할 때 SHA-1의 해시공간은 0 ~ 2^{160}-1 까지라고 알려져 있다. 따라서 이 크기의 공간을 해시 공간이라고 하고 X_0 ~ X_n 이라고 할 때 양쪽 끝을 이어 원 형태로 만든 리스트를 해시 링이라고 한다.

“해시링과 해시 공간 그림”

  • 위 해시 링에 서버를 균등하게 분포하고 반 시계 방향으로 서버가 나오기 전까지의 모든 데이터(키)를 해당 서버에 저장한다.
  • 위 명제에서 균등은 서버의 추가 및 삭제가 없을 땐 유지가 되지만 서버가 추가되거나 삭제되면 중간에 서버 노드가 생기기 떄문에 어느 노드에 키 데이터가 몰릴 수 있다. 따라서 가상 노드라는 기술을 통해 이 문제를 해결한다.
  • 가상 노드는 말 그대로 가상의 노드로 실제 서버 노드를 대신할 가상의 여러 노드를 생성하는 것이다. S1의 가상 노드 S1_1, S1_2, S1_3 … 이런 식으로 말이다. 여러개의 노드를 교차로 링에 배치하면 표준편차가 작아져서 결국 점차 균등해진다는 확률적인 계산이 나온다. 하지만 너무 많은 가상 노드는 저장할 공간을 잡아먹고 너무 적은 노드는 표준 편차를 높인다. 따라서 타협적인 결정이 필요하다.

“가상 노드와 균등 그림”

  • 마지막으로 재배치할 키를 결정하는 방법이다. 재배치란 서버가 추가되거나 삭제될 때 키들을 새로운 서버에 배정하는 과정이다. ( 그냥 반시계 방향으로 돌면된다. )
  1. 키-값 저장소 설계 비-관계형 데이터베이스이다. 이 데이터베이스는 고유 식별자를 통해서 데이터를 조회하는 구조이다. 단일 서버 키-값 저장소의 경우 너무 쉽다. 그냥 구현하면 된다. 하지만 분산 구조의 저장소일 경우 CAP정리를 이해해야한다. 일관성, 가용성, 파티션 감내
  • 일관성 - 분산 시스템에 접속하는 클라이언트는 어떤 방식으로든 같은 데이터를 받아야한다.
  • 가용성 - 일부 노드에 이슈가 있어도 응답은 항상 받아야한다.
  • 파티션 감내 - 네트워크 통신 장애에도 시스템은 동작해야한다. 이 CAP정리는 두가지 조건에 만족되면 반드시 한 조건은 희생된다는 정리이다. 정리 : 안정 해시를 통해 데이터 파티션과 확장성 그리고 다양성을 보장한다. 가용성은 백터 시계를 통해 충돌 해소(쓰기), 서버의 다중화로 읽기의 가용성 보장한다.
  1. 분산 시스템을 위한 유일 ID 생성기 대단한 기술이 들어가는 것은 아니다 그냥 상식적으로 생각했을 때 나올 법한 아이디어가 이 책에 다 나와 있다.
  • 다중 마스터 복제 K 값의 설정을 데이터베이스 서버의 수로 설정하고, 값(Value)가 들어오면 K만큼 ID값을 생성하고 각 DB에 배포한다. 생성기의 개발이 간편하지만 데이터베이스의 확장이나 삭제 시 잘 작동하도록 만들기 어렵다.
  • UUID UUID는 시스템의 정보를 유일하게 식별하기 위한 128bit의 문자열이다. 값이 충돌 될 가능성이 극히 적다. 값이 09c93e62-50b4-468d-bf8a-c07e1040bfb2 와 같은 형태이기 때문에 충돌 가능성은 극히 적다. 하지만 128bit의 긴 문자열과 Numeric인 숫자값이 아닌점 그리고 시간순이 아닌점이 단점이다.
  • 티켓 서버 티켓 서버는 말 그대로 티켓(ID)를 배정하는 서버를 중앙에 두고 DB에 연결하여 ID값을 배정받는 방식이다. 이 시스템은 중앙 통제적으로 SPOF문제점이 있다.
  • 트위터 스노플레이크 마지막 방법은 이 책에서 채택한 방법으로 가장 이상적이라고 밝히고 있다. 64bit의 평균적인 길이를 가진 ID구조를 사인, 타임스탬프, 데이터센터, 서버ID, 일련번호로 나누어 ID 안에 데이터의 위치와 시간을 유추할 수 있는 구조이다. 이 구조는 여러 전략에 따라 구조가 바뀔 수 있는 형태로 다양한 도메인에서 응용하고 각 시스템에 맞춰서 설계하면 될 듯 하다. 위 같은 ID생성 기술을 토대로 상세 설계를 할 때 다양한 점을 고려해야한다. 가령 트위터 스노플레이크에서 마지막 일렬번호의 크기가 밀리초당 들어올 수 있는 총 데이터의 갯수가 되는 것 처럼 각 데이터의 크기가 제한율에 큰 영향을 준다는 점을 인지하고 상세 설계를 진행하며 계산하고 고려해야한다.
  1. URL 단축기 설계 URL 단축기는 긴 URL이 주어졌을 때, 단축 URL을 제공하여 편의성을 제공해야합니다. 이 구조에서는 API 엔드포인트와 리다렉션 두가지 장치가 있어야 한다.. API엔드포인트는 POST와 GET으로 각각 단축된 url 등록 및 단축된 url 반환, 그리고 GET은 단축된 url을 입력하면 리다렉션 목적지 url을 반환하는 역할을 한다. 여기서 중요한 부분은 POST인 단축된 URL을 생성하고 반환하는 부분이다. URL을 단축하는 해시 함수를 생성해야한다. 이 함수는 복원이 가능해야하며 모든 값이 달라야한다. 이런 부분을 고려하고 base-62같은 알고리즘을 사용하여 해결해야한다. 또한 부하 개선 및 성능 향상을 위한 캐시서버와 같은 컴포넌트 추가를 고려하면 좋다.
  2. 웹 크롤러 설계 웹 크롤러는 검색 엔진의 인덱싱, 데이터 마이닝 등 다양한 분야에 쓰인다. 크롤러의 설계는 FLOW가 중요하다. 시작 URL에서 어떤 링크로 들어가야 유의미한지 파악하자. 이 책에서 밝히는 몇가지 필터링 기술은 다음과 같다. PDF등 파일 명의 확장자를 가진 링크는 이슈를 유발하니 필터링해야한다. 또한 방문한 URL이거나 컨텐츠인 경우 방문을 제외하는 루프를 방지하는 필터도 있다. 크롤러의 방문 방법이 DFS인가 BFS인가도 고민한다. 주로 BFS를 사용한다고 한다. 하지만 더 좋은 데이터를 빠른 시간에 끌어오는 방식은 다양히 중요도를 설정해야할 것이다. 가령 방문자 수 와 같은 데이터로 말이다.
  3. 알림 시스템 설계 알림 시스템은 ios, 안드로이드, SMS, 이메일을 지원하는 시스템으로 각 컴포넌트를 분리하여 제공하고 있다. 동작 중인 서비스와 알림 서버 그리고 각 알림을 실제로 실행하는 각 컴포넌트들 그리고 마지막 단말기로 구성된다. 이 설계에서는 알림의 무손실과 확장성을 고려하고 있다. 데이터베이스와 캐시 그리고 서버를 분리하고 알림 서버의 증설을 통한 수평적 확장이 가능하게 했다. 마지막으로 메시지 큐를 통해 무손실과 컴포넌트와 서버 사이의 결합도를 낮췄다. 이 부분에서 고려할 점은 알림의 제한율(인증), 모니터링(알림 추적), 그리고 시스템 모니터링 등이 있다.
  4. 뉴스 피드 시스템 설계 이 시스템은 뉴스 발행과 뉴스 피드 생성 두가지 파트로 나뉘어 있다.
  • 피드 발행 : 스토리를 포스팅하면 데이터를 캐시와 DB에 기록하고 새 포스팅은 팔로워의 피드에 전송된다.
  • 피드 생성 : 모든 포스팅은 시간 흐름의 역순(최신순)으로 모아서 피드에 기록된다. 피드 시스템의 설계는 저장, 전송, 알림 서비스로 나뉜다. 저장은 DB에 포스팅 데이터를 저장하는 서비스로 캐시와 DB에 각각 데이터가 기록된다. 알림 서비스는 바로 전에 언급한 알림 시스템의 역할이고 마지막 전송 서비스는 각 팔로워에게 내 포스팅을 피드에 생성 시키는 역할이다. 팔로워를 가져올 사용자 정보 캐시와 DB에 접속하고 해당 팔로워의 피드에 메시지 큐를 통해 피드에 포스팅을 저장시킨다. 이 설계는 생각보다 복잡하고 고려할 사항이 많다. 친구의 관계 그리고 피드 추천, 마지막으로 피드의 우선순위와 같은 여러가지 고려 사항이 존재한다. 인스타그램을 생각하면 편할 듯 하다.
  1. 채팅 시스템 설계 무상태 서비스, 상태 유지 서비스, 서비스 연동으로 구분할 수 있을 듯 하다. 이 책엔서는 서버와 클라이언트의 연결 방식에 대해 다음과 같이 설명한다. 폴링, 롱 폴링, 웹 소켓 → 결론 웹소켓이다. 이 서비스는 접속의 상태 (사용자 프로파일, 그룹, 인증 서비스, 서비스 탐색 ) 등 을 무상태 서비스를 통해 제공한다. 또한 상태 유지 서비스는 클라인어트와 서버 간 통신 상태를 유지하는 역할을 하고 마지막 서비스 연동은 알림 서비스와 같은 푸시 알림 서비스를 제공한다. 이 서버스는 접속 상태 표시, 로그 아웃, 접속 장애 관리, 채팅 그룹의 메시지 동기화 등 다양한 부분에서 설명을 해준다.
  2. 검색어 자동완성 시스템 설계 검색어 자동 완성은 거의 모든 검색이 필요한 서비스에서 제공하고 있다. 이 시스템은 두가지 기능으로 나뉜다. 데이터 수집 서비스, 질의 서비스이다. 데이터 수집은 질의 데이터를 실시간으로 수집하고 질의 서비스에 적용하는 역할이고 질의 서비스는 주어진 질의에 인기 검색으로 정렬하여 제공하는 서비스이다. 이 시스템의 설계는 트라이 자료구조가 99% 나머지가 1% 정도 차지하는 것 같다. 트라이 자료 구조는 접두어 문자열을 통해 빠르게 탐색할 수 있게 도와주는 문자열이다. 이 문자열을 통해 실시간으로 추천 검색어를 인기 순으로 정렬할 수있는 것이다. 이 시스템에서 불순한 검색어 삭제, 저장소 규모 확장 (샤딩), 트라이 연산(트라이 갱신 연산) 등 여러 부분에서 설명해준다.
  3. 유튜브 설계 (스트리밍 서비스) 이 파트에서 CDN와 BLOB스토리지는 따로 설계하지 않고 컴포넌트 형태로 묶는다(설계의 효율성을 위해 그렇게 한다고 책에서 밝힘). 핵심 내용은 CDN과 비디오 서버 형태로 나뉘어 인기 동영상 또는 비디오 서버에서 인코딩된 영상을 CDN에 옮겨 빠르게 안정적으로 재생한다. 속도의 최적화를 위해 분할된 비디오와 오디오를 따로 저장하고 병렬로 다운로드 및 업로드한다. 그리고 나뉜 데이터를 하나로 합치고 CDN에 업로드하여 재생한다.
  4. 구글 드라이브 설계 파일을 여러개의 블록으로 나누어 저장하며 이 저장소를 블록 저장소라고 칭한다. 고유한 해시값을 통해 블록을 찾는다. 또한 오랫동안 찾지 않은 데이터는 아카이빙 저장소로 옮겨진다. 각 객체는 메타데이터를 통해 사용자, 파일, 블록, 버전 등 다양한 데이터의 정보를 관리한다. 이 설계의 핵심은 데이터의 분할, 압축, 암호화 이다. 이 모든 과정이 블록으로 분할 압축 암호화되고 클라우드의 큰 데이터베이스 저장소에 저장된다.(s3)

마무리

이 책에서 느낀 점에서 공통적으로 밝히는 내용은 라이브 코딩 테스트와 같은 면접관과 소통하며 문제를 풀어가는 자리에 모두 적용이 될 것 같다. 문제를 명확하게 하는 과정 문제의 범위를 줄여가고 기능을 정확하게 인지하고 해결하는 과정 그리고 면접관과 소통하면 맞는 길인지 체크하고 커뮤니케이션하며 문제를 풀어가는 과정까지 문제를 정확하게 푸는 것도 중요하지만 소통하고 문제를 같이 풀어가는 과정이 중요하다고 밝히는 것 같다. 물론 내용도 백엔드/인프라 개발자에게 무척 중요하고 값진 내용들이다.

학습 목적으로 정리한 내용으로 문제가 있다면 내리겠습니다.

(이 책은 한국어판 저작권은 에이전시 원을 통해 저작권자와의 독점 계약으로 인사이트에 있습니다. 저작권법에 의해 한국 내에서 보호를 받는 저작물이므로 무단전재와 무단 복제를 금합니다.)

출처