Design News Feed System
요구사항
모바일 / 웹 모두 지원
피드 페이즈에 새로운 스토리 생성 및 조회 기능
스토리엔 이미지 혹은 비디오 포함 가능
시간 흐름 역순으로 스토리 정렬
한 명의 사용자는 최대 5,000명의 팔로워를 가질 수 있음
DAU 1,000만명
기능 정의
위와 같은 요구사항을 만족하기 위해 크게 두 가지 기능을 구현해야 한다.
피드 발행: 사용자가 스토리가 포스팅 시 해당 데이터를 캐시와 데이터베이스에 기록
새 포스팅은 팔로워의 뉴스 피드에도 전송
뉴스 피드 생성: 모든 친구의 포스팅을 시간 흐름 역순으로 정렬하여 사용자에게 제공
위 기능을 API 단위로 나누어 설계하면 다음과 같다.
피드 발행 API
POST /v1/me/feed
body: 포스팅 내용
헤더: 인증을 위한 Authorization 헤더 토큰
피드 읽기 API
GET /v1/me/feed
헤더: 인증을 위한 Authorization 헤더 토큰
상세 설계
피드 발행
피드 발행 기능을 제공하기 위한 시스템은 대략적으로 아래와 같이 구성할 수 있다.
디바이스 ──> 로드밸런서 ──> 웹서버 ──> 포스팅 저장 서비스 ──> 포스팅 캐시 ──> 포스팅 데이터베이스
├── 포스팅 전송 서비스 ──> 사용자 관계 그래프 데이터베이스
└── 알림 서비스 ├─> 사용자 정보 캐시 ──> 사용자 데이터베이스
└─> 메시지 큐 ──> 포스팅 전송 작업 서버 ──> 뉴스 피드 캐시
웹 서버: HTTP 요청을 내부 서비스로 중계
인증: Authorization 헤더 토큰을 확인하여 사용자 인증
처리율 제한: 유해한 컨텐츠 방지 및 특정 사용자가 올릴 수 있는 포스팅 수 제한
포스팅 저장 서비스: 새 포스팅을 데이터베이스와 캐시에 저장
포스팅 전송 서비스: 새 포스팅을 해당 사용자의 연관 관계에 있는 모든 사용자에게 전달
뉴스 피드 캐시에 저장해 빠르게 조회 할 수 있도록 함
알림 서비스: 팔로워에게 새 포스팅 알림 역할
포스팅 전송 서비스에서 새 포스팅을 해당 사용자의 연관 관계에 있는 모든 사용자에게 전달하는 것을 팬아웃이라고 하는데, 팬아웃 모델에는 쓰기 시점 팬아웃과 읽기 시점 팬아웃 두 가지 존재한다.
쓰기 시점 팬아웃(푸시 모델): 새 포스팅을 저장하는 시점에 뉴스 피드 갱신
뉴스 피드가 실시간으로 갱신되어 사용자가 뉴스 피드 조회 시점에 빠르게 조회 가능
사용자 모두의 뉴스 피드를 갱신하기 때문에 많은 시간 소요 문제 가능성이 존재하며 자주 이용하지 않는 사용자까지 불필요하게 갱신되는 문제가 있음
읽기 시점 팬아웃(풀 모델): 뉴스 피드를 조회하는 시점에 뉴스 피드 갱신
자주 이용하지 않는 사용자의 뉴스 피드 갱신을 방지
사용자가 뉴스 피드 조회 시점에 갱신되기 때문에 뉴스 피드 조회 시간이 길어질 수 있음
위 두 가지 방법을 혼합하여 각 장점을 취하도록 설계할 수 있다.
대부분의 사용자: 뉴스 피드를 빠르게 조회할 수 있는 것이 중요하므로 쓰기 시점 팬아웃(푸시 모델) 사용
팔로워가 아주 많은 사용자: 팔로워로 하여금 해당 사용자의 포스팅을 필요할 때 조회하는 방식으로 읽기 시점 팬아웃(풀 모델) 사용
추가적으로 안정 해시를 통해 요청과 데이터를 고르게 분산하여 처리(특정 데이터가 많이 요청되어 부하가 집중되는 것을 방지)
두 방법을 혼합하게 된 팬아웃 서비스는 다음과 같이 동작하게 된다.
사용자 관계 그래프 데이터베이스에서 친구 ID 목록 조회
사용자 정보 캐시에서 친구들 정보 조회
친구 목록과 새 스토리 포스팅 ID를 메시지 큐에 전달
포스팅 전송 작업 서버에서 메시지 큐에서 메시지를 가져와 뉴스 피드 캐시에 저장
뉴스 피드 캐시는 <post_id, user_id> 순서쌍 저장
사용자가 피드 전부를 보는 경우는 드물기 때문에 캐시의 크기를 제한하여 최근 포스팅만 저장
메모리를 절약하기 위해 id만 저장하고, 실제 데이터는 데이터베이스에서 가져옴
뉴스 피드 생성 및 조회
사용자가 보는 뉴스 피드를 생성하기 위한 시스템은 대략적으로 아래와 같이 구성할 수 있다.
디바이스 <──> 로드밸런서 ──> 웹서버(여러 대) ──> 뉴스 피드 서비스 ──> 뉴스 피드 캐시
└─> CDN ├─> 사용자 정보 캐시 ──> 사용자 데이터베이스
└─> 포스팅 캐시 ──> 포스팅 데이터베이스
사용자가 뉴스 피드 조회 요청
로드밸런서는 웹 서버 중 하나를 선택하여 요청 전달
뉴스 피드 서비스에서 뉴스 피드 캐시에 저장된 포스팅 ID 목록 조회
뉴스 피드에 표시할 사용자 이름 / 사용자 사진 / 포스팅 컨텐츠 / 이미지 등을 사용자 캐시와 포스팅 캐시에서 조회
조회된 데이터들로 뉴스 피드 생성
생성된 뉴스 피드를 사용자에게 전달
캐시
캐시는 뉴스 피드 시스템의 핵심 컴포넌트 중 하나로, 다음과 같은 정보를 저장할 수 있다.
뉴스 피드: 뉴스 피드 ID 보관
컨텐츠: 포스팅 데이터 보관, 인기 컨텐츠와 일반 컨텐츠를 구분하여 저장
소셜 그래프: 팔로워 / 팔로잉 관계 보관
행동: 사용자 행동(좋아요, 댓글 등) 보관
횟수: 좋아요 / 댓글 수 / 팔로워 수 등 보관
참고자료
Last updated
Was this helpful?