//
요즘 개발자를 위한 시스템 설계 수업 · 디렌드라 신하, 테자스 초프라
책의 마지막 네 장은 구글 독스 설계, 넷플릭스 설계, 시스템 설계 면접 준비를 위한 팁, 그리고 시스템 설계 커닝 페이퍼로 이어진다.
솔직하게 적어 두면, 이 구간에서는 하이라이트를 거의 남기지 않았다. 앞선 두 장에서 설계 템플릿이 이미 충분히 반복됐고, 같은 절차를 다시 따라가는 데서 새로 얻는 것이 적었기 때문이다. 그래서 이 장은 책의 서술을 요약하는 대신, 두 서비스가 각각 어떤 고유한 문제를 던지는지를 스스로 정리하고 별도 리서치로 메운 내용으로 구성했다.
앞선 사례들과 구글 독스가 결정적으로 다른 지점은 하나다. 여러 사용자가 같은 데이터를 동시에 수정한다.
X나 인스타그램에서는 트윗과 게시물의 작성자가 한 명이므로 쓰기 충돌이 사실상 없다. 반면 문서 협업 편집에서는 두 사람이 같은 문장의 같은 위치를 동시에 고치는 일이 일상적으로 발생한다. 여기서 3장의 일관성 논의가 전혀 다른 형태로 되돌아온다.
문제를 구체화해 보면 이렇다. 문서가 "ABC"인 상태에서 두 사용자가 동시에 편집한다.
초기 상태: "ABC"
사용자 1: 위치 1에 "X" 삽입 → "AXBC"
사용자 2: 위치 2의 "B" 삭제 → "AC"
두 연산을 그대로 서로에게 적용하면?
사용자 1 기준: "AXBC"에서 위치 2 삭제 → "AXC" (의도대로)
사용자 2 기준: "AC"에서 위치 1에 X 삽입 → "AXC" (우연히 일치)
이 예시는 운 좋게 맞았지만, 위치 인덱스가 어긋나는 조합에서는 두 사용자의 문서가 영구적으로 갈라진다. 단순히 연산을 주고받는 것만으로는 수렴이 보장되지 않는다.
운영 변환(OT, Operational Transformation) 은 들어온 연산을 그동안 적용된 다른 연산에 맞춰 변환한 뒤 적용한다. 위 예시에서 "위치 2 삭제"를 받았을 때, 그 사이에 위치 1에 삽입이 있었다는 사실을 반영해 "위치 3 삭제"로 바꿔 적용하는 식이다. 구글 독스가 채택한 방식이다.
충돌 없는 복제 데이터 타입(CRDT, Conflict-free Replicated Data Type) 은 접근이 다르다. 데이터 구조 자체를 "어떤 순서로 병합해도 같은 결과가 나오도록" 설계한다. 텍스트의 각 문자에 전역적으로 고유하고 순서를 비교할 수 있는 식별자를 부여하고, 삽입은 "이 식별자와 저 식별자 사이"로 표현한다. 위치 인덱스를 쓰지 않으므로 변환이 필요 없다.
| OT | CRDT | |
|---|---|---|
| 충돌 해결 위치 | 연산을 변환 | 데이터 구조 자체가 병합 가능 |
| 중앙 서버 | 사실상 필요 | 불필요 |
| 문서 표현 크기 | 작음 | 식별자와 툼스톤으로 커짐 |
| 구현 난이도 | 변환 함수 정확성 확보가 어려움 | 자료구조 설계가 어려움 |
| 대표 사례 | 구글 독스 | Yjs, Automerge |
"어느 쪽이 우월한가"는 결론이 나 있지 않다. 중앙 서버가 확실히 존재하는 웹 애플리케이션이라면 OT의 단순한 문서 표현이 유리하고, 오프라인 우선이나 로컬 우선(Local-first) 애플리케이션이라면 CRDT가 사실상 유일한 선택이다. 이 판단은 3장의 CAP 논의와 정확히 같은 형태다. 파티션(오프라인) 상황에서 무엇을 보장할 것인가의 문제다.
동시 편집 문제를 걷어내면 나머지는 앞선 장들에서 본 조각들의 조합이다.
넷플릭스가 던지는 고유한 문제도 하나로 요약된다. 전송해야 하는 데이터의 크기가 다른 모든 사례와 자릿수가 다르다.
트윗 하나가 수백 바이트, 인스타그램 사진 하나가 수백 킬로바이트라면, 영화 한 편은 수 기가바이트다. 이 차이가 설계의 중심을 데이터베이스에서 콘텐츠 전송으로 옮겨 놓는다.
핵심 전략은 단순하다. 콘텐츠를 사용자 가까이 미리 옮겨 둔다.
여기서 넷플릭스가 취한 접근이 흥미롭다. 일반적인 CDN은 사용자가 처음 요청할 때 원본에서 콘텐츠를 끌어와 캐시한다(Pull). 넷플릭스는 인기 콘텐츠를 트래픽이 적은 시간대에 미리 엣지 서버로 밀어 넣는다(Push). 무엇이 인기 있을지는 시청 데이터로 지역별로 예측한다.
이 방식이 가능한 이유는 콘텐츠 카탈로그가 변경되지 않고 크기가 유한하기 때문이다. 새 에피소드가 공개되는 시점을 미리 알고 있으므로, 공개 전에 배포를 끝낼 수 있다. 사용자 생성 콘텐츠 플랫폼에서는 쓸 수 없는 전략이다.
두 번째 축은 재생 품질 조절이다. 적응형 비트레이트(ABR, Adaptive Bitrate) 스트리밍은 하나의 콘텐츠를 여러 화질과 비트레이트로 미리 인코딩해 두고, 영상을 몇 초 단위 조각(Segment)으로 나눈다.
동일 콘텐츠의 인코딩 계단(ladder)
4K (15 Mbps) [seg1][seg2][seg3][seg4]...
1080p (5 Mbps) [seg1][seg2][seg3][seg4]...
720p (3 Mbps) [seg1][seg2][seg3][seg4]...
480p (1 Mbps) [seg1][seg2][seg3][seg4]...
클라이언트는 측정된 대역폭에 따라 조각 단위로 계단을 오르내린다
[1080p][1080p][720p][480p][720p][1080p]
↑ 네트워크 저하 구간
품질 판단을 클라이언트가 한다는 점이 핵심이다. 서버는 여러 품질의 조각을 준비해 두기만 하고, 실제 대역폭을 측정해 다음 조각의 품질을 고르는 것은 재생기다. 서버가 클라이언트의 네트워크 상태를 알 방법이 없으므로 판단 주체를 밖으로 밀어낸 것이다.
ABR 설계에서 실제로 어려운 부분은 알고리즘이 아니라 인코딩 비용이다. 콘텐츠 하나를 여러 해상도, 여러 비트레이트, 여러 코덱으로 인코딩하면 저장 용량과 연산 비용이 배수로 늘어난다. 그래서 콘텐츠 특성에 따라 인코딩 계단을 다르게 구성하는 접근이 쓰인다. 정적인 애니메이션은 낮은 비트레이트로도 충분하고, 빠른 액션 장면은 더 높은 비트레이트가 필요하다. 모든 콘텐츠에 같은 계단을 쓰면 어느 한쪽에서 낭비가 생긴다.
이 마지막 항목이 스트리밍 서비스 설계의 중요한 원칙이다. 기능마다 실패 허용도가 다르다. 재생이 멈추는 것은 치명적이지만, 추천 목록이 기본값으로 대체되는 것은 사용자가 알아채기도 어렵다. 이 등급을 명시적으로 나누고 각 기능의 실패가 다른 기능을 끌고 내려가지 않도록 격리하는 것이 설계의 몫이다.
마지막 두 장은 면접 준비와 요약 자료다. 여기서 다뤄지는 내용은 결국 3부 전체에서 반복된 템플릿을 압축한 것이다.
이 절차에서 실제로 평가가 갈리는 곳은 1번과 6번이다.
1번, 요구 사항 명확화 — 문제를 받자마자 아키텍처를 그리기 시작하면 범위가 무한정 넓어진다. "어느 정도 규모인가", "읽기와 쓰기 중 어느 쪽이 많은가", "일관성이 얼마나 중요한가"를 먼저 확인해 문제를 유한하게 만드는 것이 첫 단계다.
6번, 핵심 문제 심화 — 서비스마다 그 서비스를 어렵게 만드는 문제가 하나씩 있다. 지금까지 본 사례를 이 관점으로 다시 정리하면 이렇다.
| 서비스 | 이 서비스를 어렵게 만드는 문제 |
|---|---|
| URL 단축 | 고유하고 짧은 문자열을 충돌 없이 대량 발급하기 |
| 근접 서비스 | 2차원 공간 검색을 1차원 인덱스로 환원하기 |
| X / 인스타그램 | 팔로워 수 편차가 극단적인 상황에서 타임라인 만들기 |
| 구글 독스 | 동시 편집의 수렴 보장 |
| 넷플릭스 | 기가바이트 단위 콘텐츠를 사용자 근처로 미리 옮기기 |
앞의 다섯 단계는 어느 문제에나 같게 적용되는 절차이고, 6번이 그 서비스에 관한 이해를 보여주는 자리다. 템플릿은 무대를 만드는 도구이고, 승부는 그 서비스만의 문제에서 갈린다.
13개 장으로 재구성한 이 리뷰를 마무리하며 책 전체를 돌아보면, 구조와 깊이의 균형이 뚜렷하게 갈린다.
좋았던 점은 지도를 그려 준다는 것이다. 분산 시스템의 속성과 이론, 확률적 자료구조, 인프라 구성 요소, 관측 가능성, 설계 실전이 하나의 목차 안에 정렬되어 있다. 시스템 설계라는 영역에 무엇이 들어 있는지 조망하기에 이만한 구성은 흔치 않다. 3부에서 반복되는 설계 템플릿은 그대로 실무 체크리스트로 옮길 수 있다.
아쉬운 점은 각 지역이 얕다는 것이다. DNS는 더 파고들 지점에서 멈추고, 로드 밸런서는 알고리즘 나열에 가깝고, 카프카와 Neo4j는 개요에서 끝난다. 후반부 사례 설계는 뒤로 갈수록 같은 절차의 반복이 되어 12장 이후에는 밀도가 급격히 떨어진다. 하이퍼로그로그 설명처럼 단순화 과정에서 부정확해진 대목도 있었다.
별점 3.5점은 그 균형에 대한 판단이다. 시스템 설계를 처음 정리하는 사람에게는 충분히 값을 하지만, 각 주제를 실제로 다룰 때는 주제별 전문서가 따로 필요하다.
읽는 동안 계속 떠올린 생각은 설계 절차를 파이프라인으로 고정해 두는 일이었다. 요구 사항 분석 → 규모 산정 → API 설계 → 고수준 설계 → 요구 사항 검토라는 순서는 매번 기억해서 밟기보다 체크리스트로 만들어 두는 편이 낫다. 코딩 에이전트에게 설계 작업을 맡길 때에도 이 순서를 그대로 프롬프트 구조로 옮길 수 있다. 이 책에서 가장 오래 남을 것은 개별 기술 지식보다 그 절차일 것 같다.
이 글이 도움이 되셨나요?