//
요즘 개발자를 위한 시스템 설계 수업 · 디렌드라 신하, 테자스 초프라
11장은 대규모 소셜 미디어 플랫폼인 X를 설계한다. 앞선 두 장과 같은 템플릿을 쓰지만 시스템 규모가 훨씬 크기 때문에, 고수준 아키텍처에 구성 요소가 많고 각 서비스의 세부 명세 작업량도 크게 늘어난다.
기능적 요구 사항
사용자 등록 및 인증, 트윗 생성, 팔로우/언팔로우, 타임라인, 검색, 리트윗과 좋아요, 다이렉트 메시지.
비기능적 요구 사항
확장성, 가용성, 신뢰성, 지연 시간.
데이터 모델은 서비스의 핵심으로, 데이터 구조와 엔티티 관계를 정의한다. 책은 UML 클래스 다이어그램으로 표현한다.
규모 산정 항목이 앞선 장들보다 훨씬 구체적이다.
| 구분 | 산정 항목 |
|---|---|
| 서비스 규모 | 전체 사용자 수, 평균 활성 사용자 수, 사용자 1인당 트윗 생성 수, 트윗당 평균 크기, 미디어 포함 비율, 트윗 보관 기간 |
| 저장소 규모 | 트윗 저장소, 미디어 저장소, 사용자 저장소, 트윗 대역폭, 미디어 전달 대역폭, 처리 요구 사항, 캐시 크기 |
미디어가 별도 항목으로 분리된 것에 주목할 만하다. 텍스트 트윗은 수백 바이트지만 이미지 하나는 수백 킬로바이트다. 미디어 포함 비율이라는 단일 숫자가 저장소와 대역폭 산정 결과를 자릿수 단위로 바꿔 놓는다. 그래서 소셜 미디어 설계에서는 텍스트와 미디어를 처음부터 분리해 계산한다.
각 구성 요소의 역할부터 정의한다.
핵심 역할을 하는 서비스는 네 개다.
서비스를 이렇게 자른 근거가 명시적으로 나오지는 않지만, 결과를 보면 기준이 읽힌다. 읽기와 쓰기의 비율이 극단적으로 다른 기능끼리 분리한 것이다. 트윗 생성은 쓰기 중심, 타임라인 조회는 읽기 중심, 검색은 별도 인덱스가 필요한 워크로드다. 하나의 서비스에 묶여 있으면 각기 다른 확장 전략을 적용할 수 없다.
고수준 아키텍처와 API 엔드포인트를 정의한 뒤, 데이터 저장소로 데이터베이스와 객체 저장소를 나눈다. 트윗 본문과 메타데이터는 데이터베이스에, 이미지와 동영상은 객체 저장소에 둔다.
트윗 생성 과정과 조회 과정은 각각 시퀀스 다이어그램으로 명세된다.
이 절이 11장에서 가장 밀도가 높다. 책은 캐싱 전략을 다섯 가지로 나열한다.
| 전략 | 기준 |
|---|---|
| 시간 기반 슬라이딩 윈도우 캐싱 | 최근 일정 기간의 트윗만 캐시에 유지 |
| 인기도 기반 캐싱 | 조회량이 높은 트윗을 우선 캐시 |
| 하이브리드 캐싱 | 시간과 인기도를 함께 고려 |
| 예측 기반 캐싱 | 앞으로 조회될 가능성이 높은 트윗을 미리 캐시 |
| 사용자 기반 캐싱 | 사용자별 접근 패턴에 맞춰 캐시 구성 |
그리고 캐시 관리 정책으로 7장에서 본 LRU, TTL, LFU와 함께 크기 기반 삭제, 우선순위 기반 삭제를 든다.
직접 구현할 때의 고려 사항도 이어진다.
전략 다섯 개를 모두 구현할 필요는 없다. 소셜 미디어에서는 조회 분포가 극단적으로 편향되어 있어(소수 계정의 트윗이 조회량의 대부분을 차지), 인기도 기반 캐싱만으로도 히트율의 상당 부분을 확보할 수 있다. 나머지 전략은 그 위에 얹는 최적화다. 계층을 나누고 예측 캐싱까지 넣는 것은 인기도 기반만으로 부족하다는 측정 결과가 나온 다음에 할 일이다.
고수준 아키텍처와 API 엔드포인트를 정의한 뒤, 사용자 관련 데이터는 관계형 데이터베이스를 사용한다. 사용자, 팔로우 관계, 인증 정보는 구조가 안정적이고 트랜잭션 무결성이 중요하므로 합리적인 선택이다.
세부 과정은 네 가지가 각각 다이어그램과 글로 명세된다. 사용자 생성, 사용자 인증, 팔로우/언팔로우, 팔로워/팔로잉 목록 조회.
타임라인은 소셜 미디어 설계에서 가장 까다로운 부분이다. 책은 새 트윗이 생성될 때의 데이터 흐름과 타임라인 조회 과정을 각각 명세하고, 기본 타임라인과 데이터 흐름이 다른 경우도 따로 다룬다. 멘션 타임라인은 별도의 조회 과정을 갖는다.
그리고 실시간 업데이트가 필요한 경우에는 푸시 기반 업데이트를 사용해 웹소켓으로 관련 사용자에게 바로 알림을 전달한다.
타임라인 설계의 고전적인 쟁점은 팬아웃(Fan-out) 시점이다.
쓰기 시 팬아웃(Fan-out on Write) — 트윗이 생성되는 순간 모든 팔로워의 타임라인 캐시에 미리 넣어 둔다. 조회가 매우 빠르지만, 팔로워가 수천만인 계정이 트윗하면 그 순간 수천만 번의 쓰기가 발생한다.
읽기 시 팬아웃(Fan-out on Read) — 사용자가 타임라인을 열 때 팔로우 중인 계정들의 최근 트윗을 모아 정렬한다. 쓰기는 가볍지만 조회가 느리다.
실제 서비스는 둘을 섞는다. 일반 계정은 쓰기 시 팬아웃으로 처리하고, 팔로워가 임계치를 넘는 계정은 읽기 시 팬아웃으로 전환해 조회 시점에 합친다. 하나의 시스템 안에 두 전략을 공존시키는 것이 핵심이다.
사전에 정의한 아키텍처를 점검하고 API 엔드포인트를 정의한 뒤 세 가지를 다룬다.
데이터 흐름과 인덱싱 — 검색 서비스가 트윗과 사용자 정보를 받아 처리한 후 엘라스틱서치에 인덱싱하는 과정을 다이어그램으로 정의한다.
검색 쿼리 처리 과정 — 시퀀스 다이어그램으로 절차를 표현한다.
관련 점수와 순위 매기기 — 검색 결과에 점수를 매겨 사용자에게 표시할 순서를 정한다. 점수를 매기는 기준을 별도로 수립한다.
검색을 별도 서비스로 분리하고 엘라스틱서치라는 별도 저장소에 인덱싱하는 구조가 중요하다. 원본 데이터베이스에 텍스트 검색을 걸면 쓰기 성능이 함께 망가진다. 원본 저장소와 검색 인덱스를 분리하고 비동기로 동기화하는 것이 표준 패턴이다. 대신 검색 결과가 원본보다 몇 초 늦을 수 있다는 최종 일관성을 받아들이게 된다.
설계를 마친 뒤 추가로 점검할 항목들이다. 유지 보수 용이성, 비즈니스 요구 사항 부합 여부, 인기 주제와 해시태그 관리, 속도 제한과 트래픽 조절 구현 등이다.
인기 주제와 해시태그 관리는 4장에서 본 확률적 자료구조가 실제로 쓰이는 지점이다. 실시간으로 급상승하는 해시태그를 찾으려면 스트림에서 빈도를 추정해야 하고, 그것이 카운트-민 스케치가 해결하는 문제다.
12장은 인스타그램을 설계하는데, 다루는 항목이 X와 사실상 동일하다.
같은 템플릿을 다시 적용하는 구성이라, 앞 장을 읽은 다음에는 새로 얻는 것이 많지 않다. 그래서 이 장은 가볍게 지나갔다.
다만 두 서비스의 차이를 스스로 짚어 보면 연습으로서의 가치는 남는다. 인스타그램이 X와 결정적으로 다른 지점은 미디어가 콘텐츠의 본체라는 점이다. 트윗은 텍스트에 미디어가 딸려 오지만, 인스타그램 게시물은 이미지가 없으면 존재하지 않는다. 그 차이가 설계에 미치는 영향은 다음과 같다.
| 축 | X | 인스타그램 |
|---|---|---|
| 저장소 비중 | 텍스트 중심, 미디어는 부가 | 객체 저장소와 CDN이 비용의 대부분 |
| 업로드 경로 | 단순 POST | 다중 해상도 변환, 썸네일 생성 등 비동기 처리 파이프라인 필요 |
| 전송 최적화 | 텍스트 압축 | 단말·네트워크에 맞춘 해상도 선택, 포맷 변환 |
| 캐싱 대상 | 트윗 본문과 타임라인 | 이미지 자체(엣지 캐시가 결정적) |
11장은 이 책에서 가장 분량이 큰 장이다. 고수준 아키텍처에 구성 요소가 많은 만큼 API 엔드포인트와 기능 세부 명세 작업도 늘어난다. 확장성, 안정성, 성능을 중심에 두고 캐싱, 비동기 처리, 대규모 트래픽 처리 방법을 소개한다.
가장 유용했던 부분은 마이크로서비스 분해와 캐싱 전략이다. 서비스 경계를 읽기/쓰기 특성에 따라 나눈 결과와, 캐싱 전략을 다섯 가지로 분류한 목록은 실제 설계 시 참조할 만하다.
반면 인스타그램 장은 앞 장의 반복이라 밀도가 급격히 떨어진다. 이 지점부터 책의 후반부가 왜 상대적으로 얕게 느껴지는지 드러난다. 절차를 반복해 보여주는 것 자체가 학습 효과를 갖는 구성이지만, 절차를 이미 익힌 독자에게는 같은 내용의 재확인에 가깝다. 오히려 두 서비스의 차이점만 골라 비교하는 편이 더 많은 것을 남겼을 것 같다.
이 글이 도움이 되셨나요?