인스타그램 시스템 아키텍처

in #kr-dev3 years ago

Instagram은 무료 사진 및 동영상 공유 및 소셜 네트워킹 서비스이기 때문에 대부분의 사람들이 일상적인 이야기를 공유하고 생생한 추억을 기록하는 앱이라고 생각합니다.

기능 요구 사항

  1. 사용자가 사진 또는 비디오를 업로드합니다.
  2. 사용자는 사진 및 비디오를 볼 수 있습니다.
  3. 사용자는 사진 제목을 기반으로 검색할 수 있습니다.
  4. 사용자는 다른 사용자를 팔로우/언팔로우할 수 있습니다.
  5. 사용자는 검색창을 통해 사용자 ID를 검색할 수 있습니다.
  6. 팔로우하는 각 사용자에 대한 뉴스피드 만들기
  7. 사진 앨범을 보관할 수 있습니다.
  8. 채팅을 통해 이야기를 공유할 수 있습니다.
  9. 다른 사용자를 차단/제한할 수 있습니다.
  10. 다른 사용자의 게시물을 좋아하고 댓글을 달 수 있습니다.
  11. 사용자는 게시물을 작성할 수 있습니다.

비 기능 요구 사항

  1. 높은 확장성
  2. 높은 일관성
  3. 고가용성
  4. 높은 신뢰성
  5. 사용자 데이터는 내구성이 있어야 합니다(업로드한 사진은 손실되지 않아야 함).
  6. 뉴스 피드 생성을 위한 최대 대기 시간은 150ms입니다.

이제 데이터 크기 계산 을 위해 몇 가지 수학을 수행합니다.

  1. 등록된 사용자 = 5억이라고 가정
  2. 활성 사용자의 30% = 1억 5천만
  3. 등록된 연예인 수 = 10K
  4. 읽기 요청 수 = 100* 업로드(쓰기) 요청 수
  5. 피크 시간에 평균 트래픽 = X로 설정하고 6X를 처리하고자 합니다.

활성 사용자:

  1. 주 3회 게시, 각 게시물에는 1MB 이미지 + 텍스트가 있습니다.
  2. 각 게시물은 최소 10개의 좋아요와 2-3개의 댓글을 받습니다.
  3. 100명의 사용자를 팔로우하고 50명의 사용자를 팔로우합니다.
  4. 하루에 2번 뉴스 피드 새로 고침 로드

연예인

  1. 일주일에 2번 게시, 각 게시물에는 500K 이상의 이미지 + 텍스트가 있습니다.
  2. 각 게시물은 >50,000개의 좋아요 + >1,000개의 댓글을 받습니다.
  3. 500만 사용자 팔로우
  4. 하루에 2번 뉴스피드 로드

초당 쿼리(QPS)

  1. 게시하다
  • Create_post_avg = (1억 5천만 + 10K)*2/(7*24*60*60)) = 496/s
  • Create_post_peak = 496/s*6 = 3k/s

2. 좋아요

  • like_post_avg = (1억 5천만 *10+10K*50K)*(2/(7*24*60*60)) = 6.6k/s
  • like_post_peak = 6.6k/s*6 = 40k/s

3. 댓글

  • comment_post_avg = (1억 5000만82 +10K*1K) = 1k/s
  • Comment_post_peak = 1k/s *6 = 6k/s

4. 피드 팔로우

  • get_follow_feed_avg = (1억 5천만 +10K)*(2/(24*60*60))= 3.5k/s
  • get_follow_feed_peak = 3.5k/s * 6 = 21.8k/s

5. 데이터 크기

  • 64base(['a-z','A-Z','0–9','-','_'])의 user_id, 5비트 ~ 1Byte 필요
  • 5억 + 10K *5비트 ~1바이트 = 1G 사용자

용량 추정

  1. 업로드할 일일 활성 사용자 = 100만
  2. 매일 업로드되는 사진 = 500만
  3. 하루에 초당 업로드된 사진 = 57장
  4. 평균 사진 크기 = 150KB
  5. 1일 스토리지 사용량 = 500만 * 150KB = 716GB
  6. 서비스는 해당 데이터를 10년 동안 보관하고 필요한 스토리지, 716GB *365 * 10년 = 2553TB ≈ 2.6PB
  7. 조회할 수 있는 일일 활성 사용자 수 = 1000만
  8. 시간당 뉴스 피드 생성은 1000만, 이는 2800RPS(초당 요청)입니다.
  9. 하루에 1번의 검색이 있는 경우 하루에 1,000만 건의 검색이 수행되며, 이는 115RPS입니다.

시스템 구성 요소 설계

  • 사진 및 비디오 업로드 = 쓰기
  • 사진 및 비디오 보기 = 읽기
  • 읽기/쓰기 비율 = 20:80
  • 웹 서버는 동시에 1000개의 활성 연결을 지원할 수 있습니다.
  • 쓰기에는 200개의 연결이 점유되며 쓰기(업로드)는 연결을 오랫동안 열어두게 됩니다.

따라서 더 나은 방법은 쓰기와 읽기를 위해 각각 2개의 DB를 갖는 것입니다. 또한 사진의 읽기 및 쓰기 요청을 분리하면 각 프로세스를 독립적으로 확장하고 최적화할 수 있습니다. 다음 다이어그램은 읽기-쓰기 프로세스에 사용할 수 있습니다.

  1. 뉴스피드 생성 서비스
  • 팔로우하는 사용자의 최신 게시물에 대한 사용자 업데이트
  • 따라서 모든 사용자의 뉴스 피드는 고유합니다. 조합이 매우 복잡하다.
  • 새 피드를 생성하려면 시스템에서 해당 사진의 메타데이터(좋아요, 댓글, 시간, 위치 등)를 가져와 순위 알고리즘에 전달하여 메타데이터를 기반으로 뉴스피드에 정렬해야 하는 사진을 결정해야 합니다.
  • 백엔드에서 동시에 많은 테이블을 쿼리한 다음 사전 정의된 매개변수를 사용하여 순위를 지정해야 하므로 이 접근 방식은 대기 시간이 길어집니다. 뉴스피드를 생성하는 데 많은 시간이 걸립니다.
  • 따라서 사전 생성 뉴스 피드가 채택됩니다. 우리는 각 사용자에게 고유한 뉴스 피드를 생성하고 별도의 뉴스 피드 테이블에 저장하는 전용 서버를 만듭니다. 이 접근 방식을 사용하면 사용자가 업데이트를 클릭하면 DB의 뉴스 피드가 사용자에게 표시됩니다.

2. 뉴스피드 제공

  • 푸시 — 사용자가 새 사진/비디오를 업로드하면 모든 팔로워가 업데이트됩니다. 롱풀링이 사용됩니다. 사용자가 많은 사람이나 유명인을 팔로우하는 경우 서버는 사용자에 대한 푸시 업데이트를 꽤 자주 유지해야 합니다.
  • 끌어오기 — 사용자가 뉴스피드를 새로 고칩니다(서버에 끌어오기 요청). 새 게시물은 사용자가 새로고침하지 않을 때까지 표시되지 않습니다.
  • 하이브리드 접근 방식 — 팔로워 또는 유명인이 많은 모든 사용자에게 풀 기반 접근 방식 을 적용합니다. 일반 사용자를 위한 푸시 기반 접근 방식 을 적용 합니다.

3. 로드 밸런싱

  • 서버 그룹 간에 트래픽을 분산하여 웹 사이트 또는 애플리케이션의 응답 및 가용성을 향상시킵니다.
  • 최소 대역폭 방법 사용
  • 알고리즘은 초당 메가비트(Mbps)로 측정된 가장 적은 양의 트래픽을 처리하는 서버를 선택합니다.
  • 클라이언트와 서버 또는 서버와 데이터베이스 사이에 위치

데이터 아키텍처

데이터베이스 디자인

  1. 사용자 관련 데이터
  • 사용자 ID (기본 키): 사용자를 전역적으로 구별할 수 있도록 하는 고유한 사용자 ID
  • 이름 : 사용자의 이름
  • 이메일 : 사용자의 이메일 아이디
  • 비밀번호 : 로그인 기능을 용이하게 하기 위한 사용자의 비밀번호
  • 생성일 : 사용자가 등록된 일자

2. 사진 관련 데이터(AWS S3)

  • 사진 ID (기본 키): 각 사진을 식별하기 위한 고유한 10B 사진 ID
  • UserId : 사진을 업로드한 사용자의 ID
  • Path : 사진이 저장되는 Object Storage의 경로/URL
  • 위도 및 경도 : 사진의 위치를 찾기 위해 이 정보를 저장합니다.
  • 날짜 및 시간 : 사진이 업로드된 날짜 및 타임스탬프

3. 팔로워 및 팔로워 관련 데이터

  • 다음: 사용자가 뒤에 오는 모든 사용자의 UserId
  • 팔로워: 사용자를 팔로우하는 모든 사람들의 UserId

따라서 2가지 다른 데이터베이스 선택이 필요합니다.

  1. 관계형 데이터베이스(MySQL)
  2. NoSQL 데이터베이스(Cassandra)

데이터 모델

  • 일반적인 쿼리: 사용자 X가 팔로우하는 모든 사용자 가져오기 — 사용자 X에 대한 피드 보내기
  • 사용자 X를 팔로우하는 모든 사용자 가져오기 — 사용자 X의 게시물을 팔로어의 피드로 푸시
  • 활성인 모든 사용자 가져오기(활성 사용자에 대한 캐시 팔로어 피드)

인터페이스/API

  1. create_post(user_id, 이미지, 텍스트, 타임스탬프) -> 성공/실패
  2. comment_post(user_id, post_id, comment, timestamp) -> 성공/실패
  3. like_post(user_id, post_id, 타임스탬프) -> 성공/실패
  4. get_follow_feed(user_id, timestamp) -> 사용자 팔로우 목록의 최신 게시물 목록, 시간순, 제한 20
  5. get_profile_feed(user_id, user2_id, timestamp) -> user2의 최신 게시물 목록, 시간순, 제한 20

시스템 구조

게시하다

밥을 먹이다

...........................................

게시하다

밥을 먹이다

출처 : https://medium.com/interviewnoodle/instagram-system-architecture-fdbec22e48ee#gaerae.com

Sort:  

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Coin Marketplace

STEEM 0.13
TRX 0.34
JST 0.034
BTC 109437.93
ETH 4297.71
USDT 1.00
SBD 0.83