시스템 디자인 - Design A News Feed System

2022-08-17 · 엔지니어링 · 시리즈 · 시스템 디자인
시스템 디자인 - Design A News Feed System

이번 편의 뉴스피드(news feed) 설계는 읽기 중심 시스템을 고민해본 사람이라면 금방 익숙해질 주제일 듯합니다.

뉴스피드는 두 흐름으로 쪼개진다

책 내용에서는 뉴스피드를 두 흐름으로 나눠서 봅니다.

  • 피드 발행: 사용자가 글을 쓰면, 그 글을 저장하고 친구·팔로워의 피드에 반영하는 흐름.
  • 피드 조회: 사용자가 자기 피드를 열면, 팔로우한 사람들의 글을 시간순으로 모아 보여주는 흐름.

핵심 질문은 단순합니다. “내가 팔로우한 사람들의 글을 모아 보여줘야 하는데, 이 피드를 언제 만들 것인가.”

팬아웃, 쓸 때 미리 퍼뜨리느냐 읽을 때 모으느냐

피드를 만드는 시점에 따라 두 가지 모델이 갈립니다.

팬아웃 온 라이트(fan-out on write, push 모델). 누군가 글을 쓰는 순간, 그 글을 그 사람의 모든 팔로워 피드 캐시에 미리 퍼뜨려 놓습니다. 사용자가 피드를 열 때는 이미 만들어진 걸 읽기만 하면 되니 읽기가 매우 빠릅니다.

팬아웃 온 리드(fan-out on read, pull 모델). 반대로 쓸 땐 아무것도 하지 않고, 사용자가 피드를 여는 순간 팔로우한 사람들의 최신 글을 그때 모아서 만듭니다. 쓰기는 가볍지만 읽기가 무겁습니다.

팬아웃 온 라이트(쓸 때 팔로워 피드에 미리 퍼뜨려 놓기)와 팬아웃 온 리드(읽을 때 모으기)를 나란히 비교한 그림

팬아웃 방식별 트레이드오프

그럼 그냥 빠른 push가 항상 정답일까요? 그렇지 않습니다. 역시 트레이드오프가 있습니다.

push(쓸 때 미리 퍼뜨려놓기)의 단점.

  • 셀럽 문제: 팔로워가 수백만인 계정이 글 하나를 쓰면, 그 순간 수백만 개의 피드에 써넣어야 합니다. 쓰기 한 번에 너무 많은 리소스를 사용해야 합니다.
  • 낭비: 몇 달째 접속 안 한 비활성 사용자의 피드까지 미리 만들어두는 건 의미가 없을 확률이 높습니다.

pull(읽을 때 모으기)의 단점.

  • 읽기 지연: 활동량 많은 사용자가 피드를 열 때마다 수많은 사람의 글을 실시간으로 긁어모아 정렬하면 느립니다.

그래서 현실적인 해결 방법은 보통 하이브리드였습니다. 대다수 사용자는 push로 미리 만들어 빠르게 주고, 셀럽처럼 팬아웃 비용이 폭발적으로 많이 드는 경우에만 pull로 처리하는 식입니다. 따라서 상황별로 비용을 충분히 비교해보고 절충안을 찾는 게 핵심입니다.

발행과 조회의 구체적인 흐름

발행 흐름은 이렇게 흐릅니다. 글이 들어오면 웹 서버가 받아 포스트 DB·캐시에 저장하고, 팬아웃 서비스가 그래프 DB에서 팔로워 목록을 가져와 각자의 피드 캐시에 글 ID를 밀어 넣습니다(push). 메시지 큐와 워커로 이 팬아웃을 비동기로 처리하는 게 1편의 큐 이야기와 그대로 이어집니다.

조회는 그럼 어떻게 동작할까요? 인상 깊었던 건 캐시를 한 덩어리로 두지 않고 용도별로 층을 나눈다는 점이었습니다. 처음엔 과해 보였는데, 트래픽 규모를 생각하면 합리적인 선택인 듯합니다. 피드 캐시(글 ID 목록), 콘텐츠 캐시(글 본문), 소셜 그래프 캐시(팔로우 관계), 액션 캐시(좋아요·댓글 여부), 카운터 캐시(좋아요·답글 수). 한 화면을 그리는 데 필요한 데이터를 성격별로 분리해 각각 최적화하는 전략입니다.

정리

뉴스피드의 팬아웃은 결국 “읽기 비용을 쓰기 시점에 미리 치르느냐, 쓰기를 가볍게 두고 읽을 때 모으느냐”의 선택이었음. 어느 쪽도 해답이 되기보다는 결국 트레이드오프라, 대다수 사용자는 push로 미리 만들어 빠르게 주고 셀럽처럼 팬아웃 비용이 폭발하는 경우만 pull로 떼어내는 하이브리드가 현실적인 절충이었음. 캐시도 한 덩어리로 두지 않고 피드·콘텐츠·소셜 그래프·액션·카운터로 층을 나눠 각각 최적화한다는 게, 읽기 중심 시스템이 결국 어디에 돈을 쓰는지를 잘 보여준 챕터였지 싶음.

참고

Alex Xu, System Design Interview — An Insider’s Guide (Vol.1), Ch.11

시리즈 시스템 디자인 전 6편

  1. 01 Scale From Zero To Millions Of Users
  2. 02 Design Consistent Hashing
  3. 03 Design A Key-Value Store 이전
  4. 04 Design A News Feed System 현재 글
  5. 05 Design A Search Autocomplete System 다음
  6. 06 Design A Rate Limiter

댓글

GitHub(giscus) 댓글은 설정 완료 후 활성화됩니다.