가상 면접 사례로 배우는 대규모 시스테 설계 기초 #11 (뉴스 피드 시스템 설계)

박주진·2022년 6월 19일
0

문제 이해 및 설계 범위 확정

지원해야 하는 범위?

  • 모바일 앱, 웹

중요한 기능은?

  • 뉴스 피드 페이지에 새로운 스토리를 올릴 수 있어야 하고, 친구들이 올리는 스토리를 볼 수 있어야 함

뉴스 피드 스토리 정렬 기준은?

  • 시간 흐름 역순 즉 최신 순

사용자당 최대 친구 숫자

  • 5000명

트래픽 규모

  • 10 million daily

이미지, 비디오 등도 스토리에 포함될 수 있나?

개략적 설계안 제시 및 동의 구하기

중요 API

피드 발행 API

  • POST /v1/me/feed
  • body에 포스팅 내용, Authorization헤더에 API 호출을 인증하기 위해 사용

피드 읽기 API

  • GET /v1/me/feed
  • Authorization 헤더에 인증 정보

피드 발행

  • User는 모바일 앱이나 웹에서 새로운 포스팅을 올리는 주체이다.
  • Post /v1/me/feed api를 사용한다.
  • Load Balancer를 이용해서 트래픽을 웹 서버들로 분산한다.
  • Web Servers http 요청을 내부 서비스로 중계한다.
  • Post service는 새 포스팅을 데이터베이스 및 캐시에 저장
  • Fanout service는 새 포스팅을 친구들의 뉴스 피드에 푸시하고 빠르게 읽어 갈 수 있도록 캐시에 보관한다.
  • Notification service: 친구들에게 새 포스팅이 올라왔음을 알리거나 푸시 알림을 보내는 역할을 담당한다.

뉴스 피드 생성

  • User: 뉴스 피드를 읽는 주체이고 Get /v1/me/feed API를 이용한다.
  • Load Balancer를 이용해서 트래픽을 웹 서버들로 분산한다.
  • Web Servers http 요청을 News feed 서비스로 보낸다.
  • News feed service: 캐시에서 뉴스 피드를 가져오는 서비스.
  • News feed cache: 뉴스 피드를 렌더링할 때 필요한 feed ID 보관한다.

상세 설계

피드 발행 흐름 상세 설계

웹 서버와 포스팅 전송 서비스 (fanout service)에 초점을 둔다.

웹 서버

  • Authorization헤더 기반 인증 검증후 올바른 인증을 사용한 사용자만 포스팅이 가능하게 해야함
  • 처리율 제한 장치를 두어 한 사용자가 올릴 수 있는 포스팅의 수를 제한해야 한다. (스팸 및 유해 콘텐츠 방지)

Fanout Service(포스팅 전송 서비스)

  • 어떤 사용자의 새 포스팅을 그 사용자와 친구 관계에 있는 모든 사용자에게 전달하는 과정을 fanout이라고 부른다.
  • fanout에는 두가지 모델이 있다. fanout-on-write (푸시 모델), fanout-on-read(pull model)
  • fanout-on-write (푸시 모델)
    • 새로운 포스팅이 기록되는 시점에 뉴스 피드를 갱신한다. 즉 포스팅 완료시 연관된 친구들의 뉴스피드 캐시를 갱신한다.
    • 장점
      • 뉴스 피드가 실시간 갱신되며 친구 목록에 있는 사용자에게 즉시 전송
      • 뉴스 피드를 읽는데 드는 시간이 짧아진다. 왜냐하면 기록되는 순간에 뉴스피드가 이미 갱신되었음으로
    • 단점
      • 친구가 많은 사용자의 경우 친구 목록을 가져오고 그 목록에 있는 모든 친구들의 뉴스 피드를 갱신하는데 많은 시간이 소요 될 수 있다. hotkey 문제
      • 서비스를 자주 이용하지 않는 사용자의 피드를 갱신함으로 컴퓨팅 자원 낭비
  • fanout-on-read (풀 모델)
    • 피드를 읽어야 하는 시점에 뉴스 피드를 생성한다.
    • 장점
      • 비활성화된 사용자 또는 거의 사용하지 않는 사용자의 경우에 유리하다 왜냐하면 읽기 전까지 컴퓨팅 자원이 소모되지 않음으로
      • hotkey문제도 없다 왜냐하면 사전에 친구들에게 데이터 푸시 작업이 없기 때문이다.
    • 단점
      • 뉴스 피드를 읽는 데 많은 시간이 소요될 수 있다.
  • 본 설계안에서는 두가지 방법을 결합한다. celebrities(follwers가 많은 사용자)를 제외한 사용자에 대해서는 push 모델을 사용한다. 하지만 유명인들의 posts는 followers가 가져갈때 pull 모델로 가져가서 news feed를 생성한다.
  • 안정해시 기법으로 유명인들의 request또는 데이터를 보다 고루 분배할 수 있다.
    1. Graph DB에서 친구 ID 목록을 가져온다.
    2. 사용자 정보 캐시에서 친구들의 정보를 가져온다. 그후 친구들중 피드 업데이트 무시 또는 일부 사용자에게만 공개등 설정을 확인 한다.
    3. 친구 목록과 새 스토리의 포스팅 ID를 메시지 큐에 넣는다.
    4. 메시지 큐에서 꺼내어 뉴스 피드 캐시 넣는다.
      • <post_id, user_id>를 쌍으로 넣는다. 모든 post 정보나 user 정보를 넣지 않는 이유는 메모리 크기를 적정 수준으로 유지하기 위해서이다.
      • 몇천개의 post를 유저가 스크롤링 하면서 읽을 가능성은 낮기 때문에 캐시 미스가 일어날 확률은 적다.

피드 읽기 흐름 상세 설계

  1. 사용자가 피드를 읽는 요청을 보낸다.
  2. 로드 밸런서가 요청을 웹 서버 가운데 하나로 보낸다.
  3. 웹 서버는 피드를 가져오기 위해 뉴스 피드 서비스 호출한다.
  4. 뉴스 피드 서비스는 뉴스피드 캐시에서 포스팅 ID 목록을 가져온다.
  5. 뉴스 피드에 표시할 사용자 이름, 사용자 사진, 포스팅 컨텐르, 이미지 등을 사용자 캐시와 포스팅 캐시에서 가져와 완전한 뉴스 피드를 만든다.
  6. 생선도니 뉴스 피드를 JOSN 형태로 클라이언트에 응답한다.

캐시 구조

  • News Feed: 피드 아이디를 보관한다.
  • Content: post 내용을 보관하고 인기가 많은 즉 많이 조회된는 피드 내용은 hot cache에 보관한다.
  • Social Graph: 사용자간의 관계 정보를 보관한다.
  • Action: 사용자가 post에 대한 행위를 보관한다. "좋아요, 답글, 등등"
  • Counter: 좋아요 횟수, 응답 수, 팔로워 수, 팔로잉 수 등의 정보를 보관한다.

마무리

추후로 논의하면 좋을 사항들

데이터베이스 규모 확장

  • 수직적 규모 확장 vs 수평적 규모 확장
  • SQL vs NoSQL
  • Master/Slave 다중화
  • 복제본에 대한 읽기 연산
  • 일관성 모델
  • 데이터베이스 샤딩

기타

  • 웹 계층 무상태로 운영하기
  • 가능한 많은 데이터를 캐시할 벙법
  • 여러 데이터 센터 지원 방법
  • 메시지 큐를 사용하여 컴포넌트 사이의 결합도 낮추기
  • 핵심 메트릭 모니터링.ex) 트래픽이 몰리느 시간대의 QPS, 사용자가 뉴스 피드 새로고침시 지연시간

질문

  • NewsFeed Cache 구조 단순 <post_id, user_id>구조가 적당할까?
    • 조회시 friend id를 key로 조회가능?
    • 가능하다고 해도 freind 너무 많으면 in 절로 전체 조회가 가능한가?
    • user_id(feedOwner):<post_id, user_id(friend)> 요구조는 더 낫지 않을까?
      • <post_id, user_id(friend)> pair가 중복되어서 들어갈 수는 있지만 조회시 성능을 위한다면 감수 할 수 있지 않을까? 그리고 id만 들어가 공간이 많이 낭비되지는 않지 않을까?
  • fanout on read도 지금 fanout 서비스 똑같은 구조에서 가능할까?
    • 조회시 캐시에 없으면 해당 유저 친구들의 모든 피드를 조회 한후 캐시에 넣는다? 그리고 친구 한명이라도 feed를 생성하면 전체 캐시를 또 날리는 구조?
    • 아님 조회할때 마다 새로 생성?
      • 캐시가 없는 구조랑 동일한거 아닐까?
  • 하이브리드 구조에서 유명인의 글을 뉴스 피드를 생성해 놓지 않는다면 어떤 구조일까?
    - 유명인의 팔로워 -> 해당 유명인의 피드를 그때 캐시에서 모든 친구들에게 갱신??
  • 캐시 구조란? 5계층이란 무슨 의미 각 계층이 하위 계층이랑 연관 있음?
    twiter 구조?

0개의 댓글