Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions 2026-system-design-interview/02주차/김보겸/2주차.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# 4. 데이터베이스 확장
## 4.1 저장 서비스의 이해
- 저장 서비스는 일관성을 보장하기 위해 상태를 저장한다
- 이를 위해 팍소스 같은 매커니즘을 도입하기도 하고, 일관성, 복잡성, 보안, 지연 시간, 성능과 같은 다양한 트레이드 오프를 겪는다
- 가능한 모든 서비스를 상태 비저장으로 유지하고 상태 저장 서비스에만 상태를 저장하는 이유
- 스토리지 분류: 데이터베이스(SQL, NoSQL, Column-Orientied, KV), 문서, 그래프, 파일 스토리지, 블록 스토리지, 객체 스토리지

## 4.2 데이터베이스 사용 결정
- DB나 파일 시스템 중 하나를 선택하는 것은 보통 재량과 경험적 방법에 기반
- SQL 서버는 2GB 정도의 큰 파일을 저장하려면 특별 구성이 필요
- DB 객체는 전체가 메모리에 로드 되므로 DB에 파일 스트리밍은 비효율
- 큰 Blob 객체를 리더 노드에서 팔로워 노드로 복제해야 하므로 복제가 느릴 수 있음

## 4.3 복제
DB 확장에는 복제, 분할, 샤딩이 존재
- 복제본 분산: 호스트에 하나의 백업을 두고 다른 랙이나 데이터 센터 둘 다에 있는 호스트에 백업을 두는 것
- 단일 리더 복제: 모든 쓰기 작업은 단일 리더가, 읽기 작업은 팔로워들에게 위임(팔로워들의 복제 가능)
- 다중 리더 복제: 여러 리더가 동시에 쓰기 요청을 받고 복제본을 다른 리더에게 복제(Race Condition 발생 가능)
- 리더 없는 복제: 모든 노드가 동등하고, 어떤 노드에서든지 읽고 쓰기가 가능
- 정족수(합의를 위해 동의해야 하는 최소 노드 수)를 도입해 일관성 보장
- HDFS 복제

## 4.4 샤딩된 DB로 저장 용량 확장하기
- 오래된 행을 삭제하거나, 보존해야 한다면 HDFS나 카산드라와 같은 샤딩된 스토리지에 저장해야 함
- 샤딩된 RDBMS
- join 쿼리가 훨씬 느려짐(각 노드와 다른 모든 노드 사이에 상당한 네트워크 트래픽 유발)
- 집계 작업에는 DB와 애플리케이션 모두 관여. 합계나 평균과 같은 특정 집계 작업은 더 쉬움. 중앙값, 백분위 수 등의 작업은 느려짐

## 4.5 이벤트 집계하기
여러 이벤트를 단일 이벤트로 집계/결합하는 것 - 여러 번의 DB 쓰기 대신 한 번의 쓰기로 줄일 수 있음
- 단일 계층 집계: 각 호스트 메모리에 해시 테이블을 가지고 있어 일정 시간 동안 발생한 이벤트를 합계하는 방식
- 다중 계층 집계: 각 계층의 호스트가 이전 계층의 상위 호스트로부터 이벤트를 집계할 수 있음
- 분할: 7계층 로드밸런서를 사용해 들어오는 이벤트를 처리하고 내용에 따라 특정 호스트에 전달하도록 구성
- 대규모 키 공간 처리하기: 초기 집계 계층의 호스트는 메모리 보다 적은 키 공간으로 제약 - 후기 집계 계층의 호스트가 모든 키를 수용할 수 있는 충분한 메모리를 가지게 됨
- 복제와 내결함성: 체크포인팅과 데드 레터 큐를 사용하여 복구 가능. 또는 각 노드를 레디스 등 공유 인메모리 DB에 요청을 보내는 상태 비저장 노드 클러스터로 만들면 됨

## 배치와 스트리밍 ETL
- 간단하게 크론탭으로 구성 가능
- 메시징 용어: 메시징 시스템, 메시지 큐, 발생자/구독자, 메시지 브로커, 이벤트 스트리밍
- 카프카와 RabbitMQ
- 람다 아키텍쳐: 배치와 스트리밍 파이프라인을 병렬로 실행해 빅데이터를 처리하는 방식
- 카파 아키텍쳐: 단일 기술 스택으로 배치와 스트리밍 처리를 모두 수행해 스트리밍 데이터를 처리하는 소프트웨어 아키텍쳐

## 비정규화
## 캐싱
- 읽기 전략: 캐시 어사이드(지연 로딩), 읽기 통과
- 쓰기 전략: 쓰기 통과, 지연 쓰기/후속 쓰기, 쓰기 우회
- 캐시 무효화
- 브라우저 캐시 무효화: 핑거프린트를 사용하여 캐시 만료 전 파일 새 버전 교체에 대응
- 캐싱 서비스의 캐시 무효화: 무작위 교체, LRU, FIFO, LIFO
- 캐시 워밍: 캐시가 비어 있는 상태에서 사용자가 대량의 요청을 보내는 상황을 방지하기 위해 캐시를 미리 채우는 작업

# 5. 분산 트랜잭션
## 5.1 이벤트 기반 아키텍처
## 5.2 이벤트 소싱
추가 전용 로그에 데이터나 데이터 변경을 저장하는 패턴
- 모든 쓰기는 먼저 이벤트 로그에서 다뤄지고, 이 쓰기가 성공한 후 하나 이상의 이벤트 핸들러가 이 새로운 이벤트를 소비하고 다른 데이터 베이스 씀
- 모든 이벤트에 대한 audit log를 제공

## 5.3 변경 데이터 캡처(CDC)
데이터 변경 이벤트를 변경 로그 이벤트 스트림에 기록하고 이 이벤트 스트림을 API를 통해 제공하는 방식
- 이벤트 소싱보다 일관성이 높고 지연 시간이 낮음
- 이벤트 소싱에서 소비자가 처리하기 전에 요청이 로그에 일정 시간 머무를 수 있지만 CDC는 실시간으로 처리
- 트랜잭션 로그 테일링 패턴: 트랜잭션 로그 마이너라는 프로세스가 DB의 트랜잭션 로그를 테일링하고 각 업데이트를 이벤트로 생성

## 5.5 트랜잭션 감독자
트랜잭션이 성공적으로 완료되거나 취소되게 보장하는 프로세스
- 감독자는 일반적으로 불일치 수동 검토와 보상 트랜잭션의 수동 실행을 위한 인터페이스로 먼저 구현되어야 함
- 보상 트랜잭션은 수동으로 실행되었든 자동으로 실행되었든 항상 기록되어야 함

## 5.6 사가 패턴
- 분산 트랜잭션을 관리하기 위해 사용 - 모든 트랜잭션이 성공적으로 완료되어야 하고 아니면 롤백하기 위한 보상 트랜잭션이 실행됨
- 사가 패턴 자체는 상태 비저장
- 코레오그래피 방식: 각 단계가 완료된 후 다음 단계를 시작하도록 이벤트를 발행하는 방식
- 오케스트레이션 방식: 사가 관리자가 각 단계를 개별 서비스에게 요청하고, 각 서비스는 완료 여부를 사가 관리자에게 알리는 방식

# 6. 기능적 분할을 위한 공통 서비스
## 6.1 다양한 서비스의 공통 기능
- 라이브러리의 경우 라이브러리 업데이트를 사용자가 직접 해야 하고, 다른 기능을 독립적으로 확장할 수 없음
- API Gateway를 통해 공통 관심사를 중앙 집중화 할 수 있음
- 보안, 오류 검사, 캐싱, Rate Limiting, 로깅, 모니터링 등 제공

## 6.2 서비스 메시/사이드카 패턴
## 6.3 메타데이터 서비스
- 시스템 내 여러 구성 요소가 사용하는 정보를 저장
- 컴포넌트가 서로 정보를 전달할 때 전체 데이터를 넘기기보다는 메타데이터의 ID를 넘기고, ID를 기반으로 메타데이터 서비스를 통해 정보를 조회

## 6.4 서비스 디스커버리
- 서비스의 위치를 찾기 위한 서비스
- 서비스의 위치를 중앙 집중식으로 관리하고, 서비스의 위치를 중앙 집중식으로 관리하여 서비스 인스턴스의 IP 주소와 포트를 쿼리할 수 있도록 지원

## 6.5 기능적 분할과 다양한 프레임워크
- 앱, 웹
- 브라우저 앱 개발
- 모바일 앱 개발
- 크로스 플랫폼 개발
- 백엔드 개발

## 6.6 라이브러리와 서비스
- 라이브러리의 경우 라이브러리 업데이트를 사용자가 직접 해야 하고, 다른 기능을 독립적으로 확장할 수 없음
- 라이브러리의 확장성을 원할 경우 한 번 래핑하여 사용
- 서비스의 경우 서비스의 업데이트를 사용자가 직접 하지 않고, 서비스가 업데이트 되면 자동으로 새로운 기능이 제공됨

## 6.7 일반적인 API 패러다임
- OSI 모델
- REST
- GraphQL
- RPC
- 웹소켓