이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • System Design은 어떤 순서로 학습해야 설계 판단으로 이어지는가?
  • URL Shortener, Notification, Feed 같은 문제에서 무엇을 반복해서 연습해야 하는가?
  • 학습 로드맵은 성능, 정합성, 장애 격리, 운영 복잡도 판단을 어떻게 쌓는가?

개요

System Design 학습은 유명한 문제의 정답 구조를 외우는 방식으로는 오래가지 않는다.

URL Shortener는 항상 cache와 DB가 나오고, Notification은 queue가 나오고, Feed는 fanout이 나온다고 외우면 실제 요구사항이 조금만 바뀌어도 흔들린다.

좋은 로드맵은 기술 순서가 아니라 판단 순서다.

요구사항, 트래픽, 상태, 읽기/쓰기 경로, 정합성, 장애, 운영 지표를 반복해서 연결해야 한다.

학습 순서

다음 순서로 쌓으면 각 주제가 다음 주제의 입력이 된다.

  1. 요구사항을 기능/비기능/제약으로 나눈다.
  2. QPS, TPS, peak, 저장량을 대략 계산한다.
  3. 쓰기 경로와 읽기 경로를 분리해 그린다.
  4. 상태 owner와 최종 진실의 원천을 정한다.
  5. 병목이 생길 위치를 추정한다.
  6. cache, queue, replica, partition 같은 선택지를 검토한다.
  7. 선택마다 정합성, 장애 격리, 운영 복잡도 비용을 적는다.
  8. API 계약과 지표로 설계를 검증한다.

이 순서를 반복하면 기술 이름보다 설계 판단이 먼저 떠오른다.

첫 연습: URL Shortener

URL Shortener는 작은 문제처럼 보이지만 전체 흐름을 연습하기 좋다.

write path = 긴 URL 등록
read path = 짧은 URL redirect
read/write 비율 = read가 압도적으로 큼
핵심 상태 = short key와 long URL mapping
실패 기준 = 잘못된 key, 만료된 key, redirect 지연

여기서 바로 배울 것은 ID 생성 알고리즘이 아니다.

읽기 경로가 매우 많으므로 cache나 CDN이 후보가 되고, 등록 경로는 중복 key와 idempotency가 중요해진다.

클릭 로그는 redirect 성공의 조건이 아니므로 async queue로 분리할 수 있다.

이 한 문제에서 성능, 정합성, 비동기 경계를 같이 연습한다.

두 번째 연습: Notification

Notification은 queue와 retry를 연습하기 좋다.

command = 알림 발송 요청
fanout = 대상자별 메시지 생성
external dependency = Email/SMS/Push provider
failure = provider timeout, rate limit, duplicate delivery

여기서 핵심은 “보내기”가 아니라 발송 상태를 어떻게 정의하느냐다.

요청 접수, 발송 시도, 성공, 실패, 재시도 예정, 포기 상태가 필요하다.

Queue는 응답을 빠르게 하지만 중복 발송과 DLQ 운영을 만든다.

따라서 idempotency key, provider timeout, retry 정책, 사용자 알림 중복 방지가 학습 포인트다.

세 번째 연습: Feed

Feed는 읽기 성능과 정합성 trade-off를 연습하기 좋다.

write = 게시글 작성
read = 팔로워 feed 조회
fanout-on-write = 쓰기 때 feed inbox 생성
fanout-on-read = 읽을 때 관계를 따라 조합

fanout-on-write는 읽기를 빠르게 하지만 쓰기 비용과 지연 전파가 커진다.

fanout-on-read는 쓰기를 가볍게 하지만 조회가 느려질 수 있다.

유명 사용자의 게시글은 hot fanout을 만들고, muted user나 privacy 변경은 정합성 문제를 만든다.

이 문제에서는 “어떤 사용자군에 어떤 전략을 적용할지”가 중요하다.

반복 연습 템플릿

각 문제를 풀 때는 같은 순서로 증거를 남긴다.

단계질문산출물
요구사항사용자가 성공으로 보는 결과는?API 목록과 성공/실패 응답
트래픽read/write/peak는 어느 정도인가?대략 계산과 병목 후보
상태원본 데이터는 어디인가?owner와 정합성 기준
경로동기와 비동기는 어디서 나뉘는가?sequence 또는 flow diagram
선택어떤 컴포넌트를 추가하는가?trade-off 표
운영무엇을 관측하고 복구하는가?metric, alert, runbook 초안

이 템플릿은 답을 고정하지 않는다.

문제를 바꿔도 설계 판단을 반복하게 만든다.

학습이 설계 축을 바꾸는 방식

학습 주제마다 강화되는 축이 다르다.

학습 주제주로 보는 축같이 생기는 비용
Traffic estimation성능, 확장성가정 오류, 과설계
Cache읽기 성능stale data, invalidation
Queue장애 격리, 응답 시간중복, 순서, DLQ
Consistency정합성latency, UX 제약
Sharding확장성rebalancing, hot partition
Circuit breaker장애 격리fallback 품질, threshold 운영
CQRS읽기 최적화projection lag, rebuild

로드맵의 목적은 이 비용을 기술 이름과 함께 기억하는 것이다.

피해야 할 학습 방식

  • 정답 아키텍처를 먼저 외운다.
  • 문제마다 같은 그림을 그린다.
  • QPS 계산을 숫자 맞추기 문제로만 본다.
  • cache, queue, shard를 넣으면 고급 설계라고 생각한다.
  • 장애와 운영 지표를 마지막에 형식적으로 붙인다.
  • API 계약 없이 내부 구조만 설명한다.

이 방식은 면접 답변처럼 보일 수 있지만 실제 설계 문서로는 약하다.

개인 프로젝트 적용

학습한 내용을 개인 프로젝트에 적용할 때는 작게 증명한다.

  • URL Shortener라면 redirect p95와 cache hit ratio를 본다.
  • Notification이라면 retry와 중복 발송 방지를 구현한다.
  • Feed라면 fanout 전략 하나를 선택하고 한계를 적는다.
  • 모든 주제에서 생략한 컴포넌트와 전환 조건을 문서화한다.

작은 구현도 요구사항, trade-off, 지표가 있으면 설계 학습이 된다.

기업 설계로 확장

기업 수준으로 갈 때는 문제 풀이를 운영 산출물로 바꾼다.

  • 요구사항은 SLO와 owner로 연결한다.
  • 트래픽 추정은 capacity plan으로 연결한다.
  • 상태 owner는 데이터 보정과 감사로 연결한다.
  • queue 설계는 DLQ runbook으로 연결한다.
  • cache 설계는 stale UX와 invalidation 정책으로 연결한다.
  • 장애 격리는 fallback 정책과 알림 기준으로 연결한다.

이 전환이 학습 문제와 실무 설계의 차이다.

확인 질문

확인 질문

  • 확인 질문: System Design 학습에서 기술 순서보다 판단 순서가 중요한 이유는 무엇인가?
    • 답변: 실제 문제는 기술 이름이 아니라 요구사항, 트래픽, 상태, 장애 경계를 어떻게 연결하느냐로 달라지기 때문이다.
  • 확인 질문: URL Shortener에서 가장 먼저 봐야 할 trade-off는 무엇인가?
    • 답변: read가 압도적으로 많은 redirect 경로의 성능과 short key mapping의 정합성, click log의 비동기 처리 경계다.
  • 확인 질문: 로드맵이 바꿔야 하는 설계 능력은 무엇인가?
    • 답변: 성능, 정합성, 장애 격리, 운영 복잡도 중 어떤 축이 바뀌는지 선택마다 설명하는 능력이다.

참고 문서