diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/16th-study-system-design-interview.iml b/.idea/16th-study-system-design-interview.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/16th-study-system-design-interview.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..47478b9 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2e96343 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git "a/chapter01/1\354\236\245. \354\202\254\354\232\251\354\236\220 \354\210\230\354\227\220 \353\224\260\353\245\270 \352\267\234\353\252\250 \355\231\225\354\236\245\354\204\261_\354\204\270\354\244\200.md" "b/chapter01/1\354\236\245. \354\202\254\354\232\251\354\236\220 \354\210\230\354\227\220 \353\224\260\353\245\270 \352\267\234\353\252\250 \355\231\225\354\236\245\354\204\261_\354\204\270\354\244\200.md" new file mode 100644 index 0000000..fe7ba27 --- /dev/null +++ "b/chapter01/1\354\236\245. \354\202\254\354\232\251\354\236\220 \354\210\230\354\227\220 \353\224\260\353\245\270 \352\267\234\353\252\250 \355\231\225\354\236\245\354\204\261_\354\204\270\354\244\200.md" @@ -0,0 +1,164 @@ +# 시스템 설계와 확장성 + +--- + +## 1. 단일 서버 시스템 +image + +### **개념** +- 초기 단계에서는 하나의 서버에 모든 구성 요소(웹 애플리케이션, 데이터베이스, 캐시)를 포함하는 단순한 구조로 시작. +- 예: `api.mysite.com`과 같은 도메인에 사용자가 접속하면 하나의 웹 서버가 모든 요청을 처리. + +### **특징** +- 설정과 관리가 단순. +- 사용자 수가 적은 경우 적합. + +### **한계** +- 서버 자원(CPU, RAM 등)에 한계가 있어, 트래픽 증가 시 성능 저하. +- 단일 장애 지점(Single Point of Failure, SPOF): 서버 장애 시 서비스 중단. + +--- + +## 2. 수직적 확장(Scale-Up)과 수평적 확장(Scale-Out) + +### **수직적 확장** +- **개념:** 기존 서버에 더 강력한 하드웨어(CPU, RAM, 디스크 등)를 추가. +- **장점:** 초기 비용과 설정이 간단. +- **단점:** + - 하드웨어 한계가 존재(무제한 확장 불가능). + - 단일 장애 지점 문제 해결 불가. + - 고성능 서버는 매우 고가. + +### **수평적 확장** +image + +- **개념:** 더 많은 서버를 추가하여 부하를 분산. +- **구현 방법:** + - **로드 밸런서:** 트래픽을 여러 서버로 분산. + - **다중 서버:** 장애 복구 및 가용성 향상. +- **장점:** + - 무제한에 가까운 확장 가능. + - 특정 서버 장애 시에도 서비스 지속 가능. +- **단점:** 시스템 구성 및 유지보수가 복잡. + +--- + +## 3. 데이터 계층 확장: 다중화와 샤딩 + +### **다중화(Master-Slave)** +image + +- **구성:** + - **Master 서버:** 쓰기 작업 담당. + - **Slave 서버:** 읽기 작업 담당. +- **장점:** + - 읽기 성능 분산으로 전체 성능 향상. + - 장애 발생 시 Slave 서버를 Master로 승격 가능. +- **단점:** + - 데이터 복제가 지연될 가능성 있음(최신 데이터가 Slave에 반영되기까지 시간 필요). + +### **샤딩(Sharding)** +image + +- **개념:** 데이터베이스를 여러 샤드(Shard)로 나눠 저장. + - 예: 사용자 ID를 기반으로 % 연산을 통해 샤드를 결정. +- **장점:** + - 데이터 분산으로 특정 서버의 부하 감소. + - 데이터베이스 크기에 제한 없이 확장 가능. +- **단점:** + - 샤딩 키를 잘못 설계하면 데이터 불균형 발생. + - 조인 연산이 복잡해지며, 재샤딩이 필요할 수 있음. + +--- + +## 4. 캐시와 CDN(Content Delivery Network) + +### **캐시(Cache)** +image + +- **역할:** 자주 참조되거나 연산이 많은 데이터를 메모리에 저장해 응답 속도 향상. +- **전략:** + - **읽기 주도형 캐싱(Read-Through):** + - 데이터가 캐시에 있으면 반환. + - 없으면 데이터베이스에서 읽어와 캐시에 저장. + - **만료(Expiration):** + - 데이터의 만료 기간을 설정해 적절히 캐시를 갱신. + - **Eviction(방출):** + - 캐시가 가득 차면 오래된 데이터를 제거(LRU, LFU 등). + +### **CDN** +image + + +- **역할:** 정적 콘텐츠(JS, CSS, 이미지 등)를 지리적으로 분산된 서버에 캐싱하여 빠르게 전송. +- **동작 과정:** + 1. 사용자가 CDN 도메인으로 콘텐츠 요청. + 2. CDN 서버에 캐시된 콘텐츠가 있으면 반환. + 3. 없으면 원본 서버에서 가져와 캐싱 후 반환. +- **장점:** + - 사용자가 가까운 서버에서 콘텐츠를 가져오므로 로드 시간이 단축. + - 원본 서버의 부하 감소. + +--- + +## 5. 무상태 웹 계층(Stateless Web Layer) + +### **상태 정보와 무상태** +- **상태 정보(세션 데이터):** +- image + + - 특정 사용자에 대한 정보를 서버가 관리. + - 상태 정보가 특정 서버에 저장되면, 같은 서버로 요청이 전달되어야 함. +- **무상태:** + +- image + + - 상태 정보를 데이터베이스, Redis 등 외부 저장소에 분리. + - 어떤 서버로 요청이 가더라도 동일한 동작이 가능. + +### **장점** +- 서버 간 부하 분산이 용이. +- 트래픽에 따라 서버를 자유롭게 추가 및 제거 가능. + +--- + +## 6. 메시지 큐(Message Queue) + +image + +### **개념** +- 비동기 작업 처리를 위해 메시지를 큐에 저장하고, 소비자가 이를 처리. +- **예:** 사진 보정 작업(크로핑, 샤프닝 등). + +### **장점** +- 생산자와 소비자의 결합도를 낮춰 독립적 확장 가능. +- 장애 발생 시에도 작업 손실 방지. + +--- + + +## 7. 모니터링, 로깅, 자동화 + +### **모니터링** +- CPU, 메모리, 네트워크 사용량 등 서버 상태 추적. +- 주요 비즈니스 메트릭(Daily Active Users, Revenue 등) 분석. + +### **로깅** +- 시스템 오류를 추적하여 문제를 빠르게 해결. + +### **자동화** +- CI/CD를 통해 코드 테스트, 빌드, 배포를 자동화. + +--- + +## 설계 원칙 요약 +1. **무상태 웹 계층:** 서버의 상태 정보를 분리. +2. **다중화:** 모든 계층에 다중화를 도입하여 가용성 향상. +3. **캐시와 CDN:** 데이터베이스 및 서버 부하를 줄이고 성능 개선. +4. **샤딩:** 데이터베이스를 분산하여 확장 가능. +5. **메시지 큐:** 서비스 간 결합도를 낮추고 비동기 작업 처리. +6. **지속적 모니터링:** 성능과 장애를 감지해 빠르게 대처. +7. **자동화 도구:** 테스트 및 배포 과정을 자동화하여 생산성 향상. + + + diff --git "a/chapter02/2\354\236\245. \352\260\234\353\236\265\354\240\201\354\235\270 \352\267\234\353\252\250 \354\266\224\354\240\225_\354\204\270\354\244\200.md" "b/chapter02/2\354\236\245. \352\260\234\353\236\265\354\240\201\354\235\270 \352\267\234\353\252\250 \354\266\224\354\240\225_\354\204\270\354\244\200.md" new file mode 100644 index 0000000..14e9cd1 --- /dev/null +++ "b/chapter02/2\354\236\245. \352\260\234\353\236\265\354\240\201\354\235\270 \352\267\234\353\252\250 \354\266\224\354\240\225_\354\204\270\354\244\200.md" @@ -0,0 +1,91 @@ +# 개략적인 규모 추정 + +--- + +## 1. 개략적 규모 추정의 정의 +- **개념:** 시스템 설계 면접에서 요구되는 시스템 용량 및 성능 요건을 대략적으로 추정하는 과정. +- **목적:** 설계된 시스템이 요구사항을 충족할 수 있는지 평가. +- **Jeff Dean의 정의:** + - 개략적인 추정은 보편적인 성능 수치를 바탕으로 사고 실험(Thought Experiment)을 통해 값을 추정하는 것. + - 주로 시스템 설계 초기 단계에서 사용. + +--- + +## 2. 개략적 규모 추정을 위한 기본 지식 + +### **2.1 2의 제곱수** +- 데이터 크기와 볼륨은 2의 제곱수로 표현하는 것이 편리. +- **단위 변환:** + - 1 Byte = 8 Bit + - 1 KB = 2¹⁰ Byte, 1 MB = 2²⁰ Byte + - 1 GB = 2³⁰ Byte, 1 TB = 2⁴⁰ Byte, 1 PB = 2⁵⁰ Byte + +image + +--- + +### **2.2 응답 지연 값** +- Jeff Dean이 제공한 컴퓨터 연산의 응답 지연 값. + +image + +**분석 결과:** +1. 메모리는 빠르지만 디스크는 느림. +2. 디스크 탐색(Seek)은 가능한 피해야 함. +3. 간단한 압축 알고리즘은 매우 빠름. +4. 데이터 전송 전 압축을 권장. +5. 데이터센터 간 전송은 지연 시간이 크므로 신중히 설계 필요. + +--- + +### **2.3 가용성과 SLA(Service Level Agreement)** +- **가용성(High Availability):** 시스템이 중단 없이 지속적으로 동작할 수 있는 능력. +- **표현:** 가용성을 퍼센트(%)로 표현하며, 100%는 완전 가용 상태를 의미. +- **SLA:** 서비스 제공자가 고객과 약속한 가용 시간. +- **99% 이상의 가용성**이 일반적으로 요구됨. + +image + +--- + +## 3. 실전 사례: 트위터 QPS 및 저장소 요구량 추정 + +### **가정** +- 월간 활성 사용자(MAU): 3억 명 +- 50%의 사용자가 매일 접속. +- 사용자당 하루 평균 2건의 트윗 작성. +- 미디어를 포함한 트윗 비율: 10% +- 데이터 보관 기간: 5년 + +### **QPS 추정** +1. **일간 활성 사용자(DAU):** + DAU = MAU x 50% = 1.5억 명 +2. **QPS 계산:** + QPS = DAU x 2 트윗 / 24시간 / 3600초 = 약 3500 +3. **최대 QPS(Peak QPS):** + 최대 QPS = 2 x QPS = 약 7000 + +### **저장소 요구량** +1. **평균 트윗 크기:** + - tweet_id: 64 Bytes + - text: 140 Bytes + - media: 1 MB +2. **하루 미디어 저장량:** + 1.5억 x 2 x 10% x 1MB = 30TB +3. **5년간 미디어 저장량:** + 30TB x 365 x 5 = 약 55PB + +--- + +## 4. 개략적 규모 추정 시 팁 + +1. **근사치 사용:** + - 복잡한 계산 대신 적절히 반올림하여 빠르게 계산. + - 예: 99987 / 9.1 ≈ 100,000 / 10 +2. **가정 기록:** + - 문제 풀이 시 가정한 내용을 기록해 명확히 정리. +3. **단위 사용:** + - 결과값에 항상 단위를 붙여 혼동 방지. +4. **연습:** + - QPS, 최대 QPS, 저장소, 캐시 요구량, 서버 수 추정 연습 필수. + - 면접 준비 시 다양한 문제를 실습하며 절차에 익숙해질 것. diff --git "a/chapter03/3\354\236\245. \354\213\234\354\212\244\355\205\234 \354\204\244\352\263\204 \353\251\264\354\240\221 \352\263\265\353\236\265\353\262\225_\354\204\270\354\244\200.md" "b/chapter03/3\354\236\245. \354\213\234\354\212\244\355\205\234 \354\204\244\352\263\204 \353\251\264\354\240\221 \352\263\265\353\236\265\353\262\225_\354\204\270\354\244\200.md" new file mode 100644 index 0000000..31bc83b --- /dev/null +++ "b/chapter03/3\354\236\245. \354\213\234\354\212\244\355\205\234 \354\204\244\352\263\204 \353\251\264\354\240\221 \352\263\265\353\236\265\353\262\225_\354\204\270\354\244\200.md" @@ -0,0 +1,102 @@ +# 시스템 설계 면접 공략법 + +--- + +## 1. 시스템 설계 면접이란? +- **정의:** "널리 알려진 제품 X를 설계하라"는 형태의 모호한 문제를 다루는 면접 세션. +- **목적:** + - 설계 능력뿐만 아니라 협업 능력, 압박 상황에서의 문제 해결 능력, 모호한 문제를 건설적으로 해결하는 능력을 평가. + - 훌륭한 질문을 던질 수 있는 능력도 중요. +- **면접의 본질:** + - 시스템 설계 면접은 모호한 문제를 해결하는 과정을 시뮬레이션하며, 최종 설계 결과보다는 과정과 사고 흐름이 중요. + - 면접관은 지원자가 과도한 엔지니어링이나 완고함 등 부정적인 신호를 보이지 않는지 확인. + +--- + +## 2. 시스템 설계 면접의 4단계 접근법 + +### **2.1 1단계: 문제 이해 및 설계 범위 확정** +- **목표:** 문제의 요구사항을 명확히 이해하고 모호함을 제거. +- **방법:** + 1. 문제를 곧바로 해결하려 하지 말고 요구사항에 대해 충분히 질문. + 2. 가정과 단위를 명확히 작성. + 3. 요구사항 파악을 위한 질문 예시: + - 어떤 기능을 만들어야 하는가? + - 사용자는 얼마나 되는가? + - 회사가 얼마나 빨리 성장할 것으로 예상되는가? + - 기존 기술 스택이나 활용 가능한 서비스는 무엇인가? + +### **2.2 2단계: 개략적인 설계안 제시 및 동의 구하기** +- **목표:** 전체 시스템에 대한 개략적인 설계안을 제시하고 면접관의 동의를 얻음. +- **방법:** + 1. 설계안의 큰 그림을 화이트보드에 그리기. + - 주요 컴포넌트: 클라이언트(모바일/웹), API, 웹 서버, 데이터 저장소, 캐시, CDN, 메시지 큐 등. + 2. 시스템의 대략적인 성능 제약사항을 계산하며 설계안의 적합성 검토. + - 계산 과정은 소리 내어 설명하며, 필요 시 면접관에게 추가 의견을 구함. + 3. 시스템의 구체적인 사용 사례 논의: + - 설계를 구체화하는 데 도움을 줄 수 있으며, 미처 고려하지 못한 예외 케이스를 발견하는 데 유용. + 4. API 엔드포인트와 데이터베이스 스키마 포함 여부 결정: + - 문제의 범위에 따라 조정. + - 큰 시스템 설계 문제라면 생략 가능, 작은 문제라면 포함 가능. + +#### **예제: 뉴스피드 시스템 설계** +1. **요구사항 정리 후 개략적인 설계안:** + - **처리 플로우(Workflow):** + 1. **피드 발행:** 사용자가 포스트를 올리면 데이터가 캐시 및 데이터베이스에 기록되고, 친구의 뉴스피드에 반영됨. + 2. **피드 생성:** 특정 사용자의 뉴스피드는 친구들의 포스트를 시간 역순으로 정렬하여 생성. + - **구성 요소:** + - 클라이언트(모바일/웹), API, 로드 밸런서, 캐시, 데이터베이스, 메시지 큐. + +2. **설계안 다이어그램 예시:** + - **피드 발행 플로우:** + - 사용자의 포스트가 캐시에 저장되고, 친구의 뉴스피드에 반영. + - 데이터베이스에도 기록. + - **피드 생성 플로우:** + - 사용자의 뉴스피드는 친구들의 포스트를 기준으로 생성 및 정렬. + +--- + +### **2.3 3단계: 상세 설계** +- **목표:** 주요 컴포넌트의 구체적인 설계 및 성능 최적화 논의. +- **방법:** + 1. 설계 대상 컴포넌트의 우선순위를 정하기. + - 병목구간과 성능 개선 가능 지점을 집중적으로 다룸. + 2. 면접관의 요청에 따라 세부적으로 설명. + - URL 단축 서비스라면 해시 함수 설계. + - 채팅 시스템이라면 지연시간 최소화 및 사용자 상태 표시. + +#### **예제: 뉴스피드 시스템** +1. **피드 발행 플로우 상세 설계:** + - 사용자가 포스트를 올릴 때: + 1. 포스트 데이터를 캐시 및 데이터베이스에 기록. + 2. 메시지 큐를 통해 친구의 뉴스피드에 반영. + +2. **피드 생성 플로우 상세 설계:** + - 사용자의 뉴스피드 요청 시: + 1. 친구들의 포스트를 시간 역순으로 정렬. + 2. 캐시를 우선적으로 사용하고, 필요 시 데이터베이스에 쿼리. + +--- + +### **2.4 4단계: 마무리** +- **목표:** 설계 요약 및 추가 논의로 면접 종료. +- **방법:** + 1. 설계안 요약: + - 설계의 핵심 아이디어를 요약하며 면접관의 기억을 환기. + - 설계 결과를 명확히 전달. + 2. 추가 논의: + - **병목구간**: 서버 오류나 네트워크 장애 시 시스템 반응. + - **운영 이슈**: 모니터링, 로그 수집, 시스템 배포 방식. + - **확장성 고려**: 현재 설계로 천만 사용자 이상을 지원하기 위한 방안 논의. + 3. 미처 다루지 못한 부분 제안: + - 필수적이지 않지만 추가 개선 가능한 사항을 간단히 언급. + +--- + +### **시간 배분 (45분 기준)** + + +1. 문제 이해 및 설계 범위 확정: 3~10분 +2. 개략적 설계안 제시 및 동의: 10~15분 +3. 상세 설계: 10~25분 +4. 마무리: 3~5분