본문 바로가기

Architecture

[Architecture]뉴스 피드 시스템설계

개요

이 시스템의 핵심은 효율적인 데이터 분배 메커니즘인 'Fanout'에 있습니다. Fanout-on-Write와 Fanout-on-Read 전략을 적절히 조합하여, 수백만 명의 사용자에게 실시간으로 관련성 높은 콘텐츠를 제공할 수 있습니다.

이 시스템은 크게 피드 발행과 뉴스 피드 생성 두 가지 주요 프로세스로 구성됩니다. 피드 발행 과정에서는 새로운 콘텐츠를 효율적으로 저장하고 배포하며, 뉴스 피드 생성 과정에서는 개별 사용자에 맞춘 최신 콘텐츠를 신속하게 조합합니다.

성능 최적화를 위해 캐싱, CDN, 비동기 처리 등의 기술을 활용하며, 이를 통해 대규모 트래픽과 데이터를 효과적으로 관리합니다.

시스템 요구사항

뉴스 피드 시스템은 다음과 같은 요구사항을 충족해야 합니다.

  • 모바일 및 웹 플랫폼 지원
  • 사용자가 새로운 스토리를 포스팅하고 친구들이 볼 수 있어야 함
  • 피드는 시간 역순으로 표시
  • 사용자당 최대 5,000명의 친구 허용
  • 일일 활성 사용자(DAU) 1,000만 명 지원
  • 이미지 및 비디오 등 미디어 파일 포함 가능

핵심 개념: Fanout-on-Write vs Fanout-on-Read

뉴스 피드 시스템 설계에 있어 가장 중요한 개념은 'Fanout'입니다. 이는 데이터를 여러 목적지로 분배하는 과정을 의미합니다. 두 가지 주요 접근 방식이 있습니다.

Fanout-on-Write (쓰기 시 팬아웃)

  • 정의: 사용자가 콘텐츠를 생성하거나 업데이트할 때 즉시 팔로워의 뉴스 피드에 전파. 즉, 쓰기 작업이 발생할 때마다 팬아웃이 이루어집니다.
  • 장점:
    • 읽기 속도 개선: 사용자가 뉴스 피드를 열람할 때, 이미 준비된 데이터를 빠르게 읽을 수 있습니다. 복잡한 쿼리나 조인이 필요 없어 읽기 작업이 빠릅니다.
    • 읽기 부하 감소: 많은 사용자가 동시에 읽기 작업을 할 때 발생할 수 있는 부하를 줄일 수 있습니다.
  • 단점:
    • 쓰기 부하 증가: 한 사용자의 콘텐츠가 수천 또는 수백만 명의 팔로워에게 전파될 때, 그만큼의 쓰기 작업이 발생하여 부하가 증가합니다.
    • 저장 공간 사용량 증가: 각 사용자의 뉴스 피드를 미리 저장해야 하므로, 저장 공간 사용량이 증가합니다.
    • 데이터 일관성 유지의 어려움: 콘텐츠가 업데이트되면 모든 관련 뉴스 피드를 업데이트해야 합니다. 이는 복잡하고 시간이 많이 소요될 수 있습니다.
  • 예시:
    • Instagram이나 Facebook과 같은 소셜 미디어 플랫폼에서 사용자가 게시물을 공유하면, 이 게시물은 그 사용자의 팔로워들의 뉴스 피드에 즉시 반영됩니다.

Fanout-on-Read (읽기 시 팬아웃)

  • 정의: 사용자가 뉴스 피드를 요청할 때마다 관련 콘텐츠를 실시간으로 검색 및 집계. 즉, 사용자가 읽기 작업을 요청할 때마다(on-demand) 팬아웃이 이루어집니다.
  • 장점:
    • 비활성화된 사용자 또는 서비스에 거의 로그인하지 않는 사용자의 경우 유리한 모델입니다.
    • 쓰기 부하 감소: 쓰기 작업이 간소화되어 부하가 감소합니다.
    • 저장 공간 절약: 미리 뉴스 피드를 저장할 필요가 없으므로 저장 공간을 절약할 수 있습니다.
    • 항상 최신 데이터 제공: 사용자가 최신 상태의 뉴스 피드를 볼 수 있도록 보장합니다.
  • 단점:
    • 읽기 부하 증가: 사용자가 뉴스 피드를 요청할 때마다 복잡한 쿼리가 실행되어 부하가 증가합니다.
    • 읽기 속도 저하 가능성: 데이터를 집계하고 제공하는 데 시간이 걸릴 수 있어, 응답 시간이 느려질 수 있습니다.
  • 예시: 전통적인 블로그나 포럼에서 사용자가 페이지를 방문할 때마다, 시스템이 최신의 댓글이나 글을 데이터베이스에서 검색하여 보여줍니다.

실제 구현에서는 이 두 방식을 적절히 조합하여 사용하는 것이 일반적입니다.

설계: 피드 발행 시스템

피드 발행 시스템은 사용자가 새로운 스토리를 포스팅할 때 작동합니다.

  • 피드 발행: 사용자가 스토리를 포스팅하면 데이터가 캐시와 데이터베이스에 기록되고 친구의 뉴스 피드에 전송된다.
  • 뉴스 피드 생성: 모든 친구의 포스팅을 시간 흐름역순으로 모아서 만든다.

  1. 웹 Server:
    • 올바른 인증 토큰을 Authorization 헤더에 넣고 API를 호출하는 사용자만 포스팅을할 수 있습니다.
    • 스팸을 막고 유해한 콘텐츠가 자주 올라오는 것을 방지하기 위해 특정 기간 동안 한 사용자가 올릴 수 있는 포스팅 수의 제한을 둡니다.
  2. 포스팅 전송(fanout) 서비스: Fanout-on-Write/Read 두 접근 방식을 적절히 조합하여 사용합니다.
    • 그래프 Database에서 친구 ID 목록 조회
    • 사용자 정보 캐시에서 친구 정보 조회. 이후 사용자 설정에 따라 친구 가운데 일부를 제외합니다.
    • message queue에 친구 목록과 새 포스팅 ID 삽입
    • Fanout 작업 서버가 message queue에서 데이터를 가져와 뉴스 피드 캐시(post_id, user_id) 업데이트

또는 가장 인기 있는 콘텐츠는 Fanout-on-Write 방식으로 미리 캐싱하고, 나머지는 Fanout-on-Read 방식으로 실시간으로 처리할 수도 있습니다.

  • 그 외 서비스
    • 포스팅 저장 서비스: 새 포스팅을 데이터베이스와 캐시에 저장
    • 알림 서비스: 친구들에게 새 포스팅 알림 전송

설계: 뉴스 피드 생성 시스템

사용자가 뉴스 피드를 요청할 때 작동하는 시스템입니다.

  • 뉴스 피드 서비스: 캐시에서 뉴스 피드를 가져오는 서비스
  • 뉴스 피드 Cache: 뉴스 피드를 렌더링할 때 필요한 피드 ID 보관

  1. 사용자가 뉴스 피드 요청 (/v1/me/feed)
  2. 웹 서버가 뉴스 피드 서비스 호출
  3. 뉴스 피드 서비스가 뉴스 피드 Cache에서 포스팅 ID 목록 조회
  4. 뉴스 피드에 표시할 사용자 이름, 사용자 사진, 포스팅 콘텐츠, 이미지 등을 사용자 Cache와 포스팅 Cache에서 가져와 완전한 뉴스 피드를 만듭니다. 미디어 콘텐츠는 CDN에 저장하여 빨리 읽어올 수 있도록 합니다.
  5. 생성된 뉴스 피드를 JSON 형태로 클라이언트에 응답 전송

최적화 전략

  1. 하이브리드 접근 방식:
    • 인기 있는 콘텐츠는 Fanout-on-Write로 미리 캐싱
    • 나머지 콘텐츠는 Fanout-on-Read로 실시간 처리
  2. CDN 활용: 미디어 콘텐츠를 CDN에 저장하여 빠른 접근 보장
  3. 캐싱 전략: 사용자 정보, 포스팅 내용 등을 효율적으로 캐싱하여 데이터베이스 부하 감소
  4. 비동기 처리: 팬아웃 작업을 비동기적으로 처리하여 시스템 응답성 향상

이러한 설계와 최적화 전략을 통해, 대규모 사용자를 지원하는 효율적이고 확장 가능한 뉴스 피드 시스템을 구축할 수 있습니다.

가상 면접 사례로 배우는 대규모 시스템 설계 기초