Featured image of post [Book] 가상 면접 사례로 배우는 대규모 시스템 설계 기초 Vol. 1

[Book] 가상 면접 사례로 배우는 대규모 시스템 설계 기초 Vol. 1

⚠️ 이 글은 기계 번역 위주로 번역되었습니다.

원문은 (en) [Book] System Design Interview Vol. 1를 참고해주세요.

책 개요

★★★★★ - 대규모 시스템 아키텍처에 대한 궁금증이 있거나 첫 번째 소프트웨어 엔지니어로 취업을 준비하는 학생들에게 강력히 추천합니다. 관련 분야에서 일하고 있는 엔지니어들도 시스템 아키텍처의 전반적인 개념을 리뷰할 수 있습니다!

책에 대한 개인적인 인상

  • 컴퓨터 과학의 기본 개념을 리뷰할 수 있었습니다. 그러나 동시에 조금 지루했습니다.

  • 동일한 시스템과 개념인 알림 시스템, 캐싱, 샤딩 및 메시지 큐가 반복적으로 소개되고 언급되어 다른 상황을 상상할 때 동일한 시스템을 쉽게 이해하고 재사용할 수 있었습니다.

    • 인터넷에서 무작위로 글을 읽고 있는 경우에는 어떤 시스템과 개념이 정확히 무엇인지 모호할 수 있습니다. 예를 들어, “이 글에서 언급된 알림 서비스는 정확히 어떤 것인가요?“와 같은 질문이 생길 수 있습니다.
    • 그러나 책에서는 비슷한 알림 시스템을 재사용하여 모호함이 제거되었습니다.
  • 가상 면접자가 다음과 같은 질문을 한 이유를 이해하지 못했습니다: 예를 들어, 업로드 및 동영상 시청이 주요 기능임을 알고 난 후 “국제화가 필요한가요?“와 같은 질문을 하는 것입니다.

    예를 들어, 사용자가 친구를 몇 명 가질 수 있는지는 중요한 포인트가 아님에도 불구하고 “사용자는 몇 명의 친구를 가질 수 있나요?“와 같은 질문을 하는 것입니다.

  • 컴퓨터 과학 분야에서 대기 시간과 데이터 크기와 관련된 일반적인 경우의 범위를 요약하는 것이 나에게는 새로웠습니다.

각 장 요약

1장: 제로에서 백만 사용자까지 규모 확장

  • 기본적인 컴퓨터 과학 개념 다룸:
    • 데이터베이스, 확장성, 캐시, CDN, 상태 비저장(stateless) vs 상태 저장(stateful), 데이터 센터, 메시지 큐, 로그, 지표(metric)

2장: 봉투 뒷면 계산

  • 컴퓨터 과학에서 지연 시간과 데이터 크기에 관련된 측정 지표에 대한 직관을 키움
    • 어떤 작업은 나노초로 처리되어야 하는지
    • 어떤 작업은 밀리초로 처리되어야 하는지

3장: 시스템 설계 면접을 위한 프레임워크

  • 면접 자체에 대해 다룸
  • 4단계를 설명함
    1. 문제를 이해하고 아키텍처의 범위를 정의하기
    2. 대략적인 아키텍처 제안과 협상
    3. 상세한 아키텍처 설계
    4. 마무리

4장: 요청 제한자(Rate Limiter) 설계

  • 요청 제한 알고리즘 다룸: 토큰 버킷, 제한 버킷, 고정 창 카운터, 이동 창 로그, 이동 창 카운터
  • 몇 일 후에도 개념을 다시 확인할 수 있었음
  • 나에게는 새로운 X-Ratelimit-* 헤더 사용 방법을 배움

5장: 일관성 해싱(Consistent Hashing) 설계

  • 일관성 해싱의 개념을 설명함
  • 책에서의 설명이 어려워 보였으며, 다른 인터넷의 기사를 참고하는 것을 권장함
    • 예시로는 https://dev.to/karanpratapsingh/system-design-consistent-hashing-1dbl을 참고함

      R = K / N
      

      여기서,

      R: 재분배가 필요한 데이터 K: 파티션 키의 개수 N: 노드의 개수

      간단하게 말하면 가상 노드를 사용하는 일관성 해싱에서 데이터는 전체 데이터 / 노드의 수로 재분배되어야 함

      • 예를 들어, 300개의 데이터와 3개의 노드(즉, 1(1~100), 2(101~200), 3(201~300))가 있다고 가정하고, 노드 1개를 추가한다고 가정해보자.
        • 일관성 해싱을 사용할 경우 → 1(1~75), 2(101~175), 3(201~275), 4(76~100, 176~200, 276~300)
          • 1 → 4: 25
          • 2 → 4: 25
          • 3 → 4: 25
          • 데이터의 75 (= 300 / 4)만 재분배됨!
        • 일관성 해싱을 사용하지 않을 경우 → 1(1~75), 2(76~150), 3(151~225), 4(226~300)
          • 1 → 2: 25
          • 2 → 3: 50
          • 3 → 4: 75
          • 데이터의 절반(150/300)이 재분배됨

Chapter 6: 분산 시스템에서 키-값 저장소 설계

  • CAP 이론 소개 - 분산 시스템에는 CP와 AP 두 가지 종류가 있다.
    • CP - 네트워크 분할 시 일관성을 위해 가용성을 포기한다.
    • AP - 네트워크 분할 시 호환성을 포기하고 시스템을 실행하며 데이터 충돌이 발생할 수 있다.
    • CA - 네트워크 분할은 불가피한 현상이므로 네트워크 분할을 허용해야 한다.
    • 가용성과 일관성을 위한 복제의 트레이드오프
    • 일관성 모델 소개: 강한 일관성, 약한 일관성, 최종 일관성
    • 일관성 부족에 대한 해결책: 데이터 버전화
    • 하트비트와 고립 프로토콜
    • 복제된 데이터의 균형 재조정을 위한 Merkle 트리
  • 너무 많은 개념과 기술이 소개되었다.

Chapter 7: 분산 시스템에서 고유 ID 생성기 설계

  • 이 부분부터 책이 더 흥미로워졌다. 다음 부분은 나의 이전 경험과 오랜 궁금증과 관련이 있다.
  • 고유한 ID를 생성하기 위한 방법
    • 다중 마스터 복제 (SQL)
      • 각 샤드 내에서 증가를 보장한다.
      • 모든 샤드 간의 순서는 보장되지 않는다.
    • UUID
      • 너무 길다 (128비트)
      • 시간에 따라 정렬할 수 없다.
      • ID는 숫자가 아닐 수 있다.
    • 고유한 ID를 발급하는 티켓 서버
      • 티켓 서버는 고유한 ID를 발급하기 위해 전용 서버로 사용되지만, 이는 SPOF(단일 장애 지점)이며 동기화와 일관성 때문에 복제하기 어렵다.
    • Twitter 스노우플레이크
      • “분할 정복” 방식의 메서드. 이 방법은 ID를 여러 부분으로 나눈다.
      • <타임스탬프, 데이터센터 ID, 서버 ID, 일련번호>
        • 타임스탬프 - Twitter에서 정의한 시작 시간 이후의 타임스탬프
        • 일련번호 - 현재 밀리초 내에서 증가하는 번호
      • 동일 데이터 센터 내에서 타임스탬프에 따라 정렬할 수 있다.
      • 동일 데이터 센터 및 동일 서버 내에서 여러 데이터의 타임스탬프가 동일하더라도 일련번호를 통해 각 데이터를 구분할 수 있다.

Chapter 8: URL 단축 서비스 설계

  • 이 부분에서 책은 블룸 필터를 많이 언급했다.
  • 이 부분은 마이크로서비스라고 부를만하겠다. 재미있었다.
  • 데이터베이스의 테이블 구조는 매우 간단하지만, 서비스는 높은 성능을 요구했다.
    • 테이블 구조: <ID>, <단축 URL>, <원본 URL>

Chapter 9: 웹 크롤러 설계

  • 특별히 흥미로운 내용은 없었다.
  • 블룸 필터가 반복적으로 언급되었다.
  • 예의 바르게 동작하기가 재미있었다.
  • 중복된 컨텐츠를 걸러내기 위해 체크섬을 사용했다.

Chapter 10: 알림 시스템 설계

  • 당근마켓에서 Go 서버 엔지니어 인턴으로 근무했을 때 알림 시스템 팀에 참여한 경험이 있어서 많은 흥미를 갖게 되었다.
  • 이 시스템과 비슷한 알림 플랫폼이 있었는데, “이게 맞는 건가..? 정말로 이런 시스템이 필요한 건가..?“와 같은 의문이 있었다. 하지만 이 책에서 비슷한 시스템이 소개되었던 것을 보고 꽤나 반가웠다!
  • 메시지 큐, 워커 패턴, 큐 모니터링 및 속도 제한
  • 알림 내용에 대한 템플릿 사용 (예: {{ USERNAME }}님을 위한 새로운 제품: {{[product.name for product in PRODUCTS]}}!)
  • 로깅 및 손실 발생 시 재시도 (오류 발생 시 로그를 확인할 수 있음)
  • 클라이언트와 알림 시스템 사이의 보안 (인증). 인증된 클라이언트만 API 키, 앱 비밀키, JWT 토큰 또는 mTLS를 사용하여 알림 시스템에 요청을 보낼 수 있다.

Chapter 11: 뉴스 피드 시스템 설계

  • 처음에 Redis in Action에서 동일한 패턴(push on write)을 접했을 때 이해하지 못했던 부분이었다.
    • 누군가 트윗을 작성하면, 팔로워들의 타임라인은 해당 트윗에 대한 정보를 각각의 팔로워의 ZSET에 푸시하여 업데이트된다(팔로워들에게 fan out). 그래서 그들의 타임라인은 항상 최신 상태를 유지한다. 이것은 “push on write"라고 불린다.
  • 처음에는 작성자의 게시글을 보지 않도록 설정한 팔로워와 활동하지 않는 사용자로 인해 시스템이 완전히 공감되지 않았다. 하지만 이 책을 통해 그들을 미리 필터링하고 “pulling on write"하는 기술을 알게 되었다.
  • “push on write"와 “pull on read"를 장단점을 기반으로 비교
  • 캐싱도 여기에서 적극적으로 사용되었다.

Chapter 12: 채팅 시스템 설계

  • 채팅 서비스는 쓰기 작업에 대한 높은 수요가 있으며 서버는 클라이언트에게 새로운 메시지에 대한 알림을 할 수 있어야 한다.
  • 쓰기 수요가 높은 경우 연결을 유지하는 것이 효율적이다. 매번 새로운 연결을 생성하는 오버헤드를 줄인다.
  • 폴링: 연결을 유지한 후 서버에서 주기적으로 새로운 데이터를 폴링할 수 있다.
  • 웹소켓: 더 나아가 웹소켓을 활용할 수도 있다.
    • 한 번 연결이 형성되면 프로토콜이 간단한 HTTP에서 웹소켓으로 업그레이드된다.
    • 연결을 유지하기 위한 서비스는 상태를 유지하는 서비스가 되기 쉽다.
  • 책은 데이터베이스의 테이블 구조가 목적에 따라 약간 다르다고 언급했다. 이것은 1 대 1 채팅인지 그룹 채팅인지에 따라 달라진다는 것을 의미한다. 그룹 채팅의 경우 그룹 ID 열이 추가된다.
    • ⬆️ 이 부분은 완전히 동의하지 않았다. 테이블 구조 측면에서 1 대 1 채팅과 그룹 채팅을 동일한 방식으로 처리할 수 있다.

      이 책에서 설명한 패턴에 따라 동일한 채팅 방에서 사용자 수가 적은 경우, 각 사용자 또는 디바이스마다 메시지 큐가 생성되므로 상당한 수의 메시지 큐가 생성될 수 있다.

      이 부분에서 Kafka나 다른 메시지 큐를 사용할 때 과도한 개수의 큐의 사용으로 인한 문제의 가능성에 대해 걱정되었다.

Chapter 13: 검색 자동완성 시스템 설계

  • 주로 트라이(Trie)라는 트리 기반 데이터 구조를 활용하는 것에 중점을 둔다.
  • 데이터 양이 많을 때 데이터 구조가 얼마나 중요한 역할을 하는지 인상적이었다.
  • Google, Instagram, Slack 등과 같은 대규모 IT 서비스에 저장된 데이터의 규모를 상상할 수 없었다.
  • 데이터 샤딩하는 방법
    • <a~z>부터 시작하여 샤딩하기
    • <aa~zz>로 샤딩하기
  • 브라우저(클라이언트 측) 캐싱

Chapter 14: 유튜브 설계

  • 대학생 시절 작은 스타트업에서 서버 엔지니어로 일하면서 다루었던 주제를 다시 접하게 되어 기쁘다.
  • 비디오 변환 - HLS (HTTP Live Streaming)과 같은 적응형 스트리밍, 비트레이트
    • AWS에서 제공하는 관리형 서비스 예시: AWS Elemental MediaConvert, AWS Elastic Transcoder
  • 사전 서명된 URL: 사용자가 비디오를 직접 클라우드 스토리지에 업로드하고 서버가 큰 객체를 클라우드 스토리지로 프록시하지 않도록 하는 기능
  • SNS에서 했던 것과 같은 방식을 적용하여 인기 있는 비디오와 다른 비디오를 다르게 처리할 수 있다.
    • 인기 있는 비디오인 경우 CDN을 활용하는 것이 좋다.
    • 인기 없는 비디오인 경우 서버 자체를 통해 비디오를 제공하는 것이 효율적일 것이다.

Chapter 15: 구글 드라이브 설계

  • 새 파일을 업로드하고 상태 변경을 알리는 일련의 순서를 보여주는 순서도가 마음에 들었다. 우리 회사에서도 일부 순서를 설명할 때 비슷한 순서도를 사용한다.
  • 이 책에서도 S3를 거대한 저장 시스템으로 사용하는 것을 명확하게 지지했다.
  • 압축, 아카이빙, 캐싱에 대해서도 언급되었다.

Chapter 16: 계속해서 학습하기

  • 특별한 내용은 없었다.

마무리

이 책은 한국 소프트웨어 엔지니어들 사이에서 가장 인기 있는 책 중 하나이다. 나는 이 책을 읽고 싶어했었고, 마침내 읽게 되었다 🙂

이 책의 초반부에서 솔직히 지루하다는 느낌을 받았다. 그러나 책의 중간부터는 대학 시절부터 가지고 있던 경험과 궁금증과 관련된 내용이 나와서 흥미를 더 끌 수 있었다.

이 책이 거대한 규모의 시스템 아키텍처를 설계하는 등의 내용을 얻기 위한 유일한 선택지는 아니라고 동의한다. 인터넷에서도 그런 내용을 찾을 수 있다. 하지만 나는 방금 전 장에서 배운 지식을 바로 다음 장에서 관련된 내용으로 연결할 수 있었던 것이 좋았다. 그 덕분에 지식을 보다 쉽게 받아들일 수 있었다.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Hugo로 만듦
JimmyStack 테마 사용 중