Skip to content

11장 X 서비스 설계 #1602

Description

@jongfeel

11장 X 서비스 설계

11.1 기능적 요구 사항

  • 사용자 등록 및 인증
  • 트윗 생성
    • 사용자는 최대 글자 수(예 280자)로 정해진 짧은 메시지를 작성할 수 있어야 합니다.
    • 트윗에는 텍스트, 해시태그, 다른 사용자를 언급하는 멘션이나 이미지, 동영상 같은 미디어를 첨부할 수 있습니다.
  • 팔로우/언팔로우
    • 사용자 관계를 나타내는 팔로우 그래프는 관리할 수 있어야 합니다.
  • 타임라인
    • 타임라인은 사용자가 팔로우하는 계정의 트윗을 시간 순서대로 보여 주는 핵심 기능입니다.
    • 사용자의 트윗 생성 시간과 선호도를 반영하여 각 사용자에게 맞는 내용을 효율적으로 생성해서 타임라인에 표시해야 합니다.
    • 실시간 업데이트를 지원하여 사용자가 새로운 트윗을 바로 확인할 수 있어야 합니다.
  • 검색
    • 사용자는 키워드, 해시태그, 사용자 이름을 기반으로 트윗이나 다른 사용자를 검색할 수 있어야 합니다.
  • 리트윗과 좋아요 기능
    • 사용자는 다른 사용자의 트윗을 자신의 팔로워에게 공유할 수 있는 리트윗 기능을 사용할 수 있어야 합니다.
    • 리트윗은 원본 트윗의 메타데이터와 출처 정보를 유지하면서도 효율적으로 처리될 수 있어야 합니다.
    • 사용자는 트윗에 공감하거나 동의할 때 ‘좋아요’를 누를 수 있어야 합니다.
  • 다이렉트 메시지
    • 다이렉트 메시지 내에 포함된 사생활을 보호할 수 있는 적절한 접근 제어와 암호화가 필요합니다.

11.2 비기능적 요구 사항

  • 확장성
    • 많은 사용자와 트윗을 처리할 수 있도록 시스템을 설계해야 하며, 사용자 수가 늘거나 트래픽이 몰리는 상황에서도 문제없이 대응할 수 있어야 합니다.
    • 서버를 추가하고 부하를 분산시켜 수평적으로 확장할 수 있어야 합니다.
    • 트윗 서비스나 타임라인 서비스 같은 개별 구성 요소를 독립적으로 확장할 수 있는 구조를 갖추어야 합니다.
  • 가용성
  • 신뢰성
  • 지연 시간
    • 트윗 생성, 타임라인 보기, 알림 받기 같은 핵심 기능에서는 지연 시간을 최대한 줄여야 합니다.
    • 캐싱이나 콘텐츠 전송 네트워크 등 효율적으로 데이터를 조회할 수 있는 방법을 활용하여 지연 시간을 최소화해야 합니다.

11.3 데이터 모델

image

Figure 11.1: UML-style class diagram for different data models

  • User 엔티티: 사용자 정보를 관리하는 구조입니다. 사용자 이름, 이메일, 비밀번호 해시, 프로필 사진, 소개글, 위치, 웹 사이트 등 프로필 정보를 저장합니다. user_id를 기본 키로 사용합니다.
  • Tweet 엔티티: 사용자가 작성한 트윗을 나타냅니다. 트윗 내용, 작성자의 user_id, 작성 시각, 미디어 URL(첨부된 경우), 위치 정보, 리트윗 수와 좋아요 수를 포함합니다. tweet_id를 기본 키로 사용합니다.
  • Follow 엔티티: 사용자 간의 팔로우 관계를 나타냅니다. 누가 누구를 팔로우하는지 follower_id와 followee_id로 저장합니다. created_at은 해당 팔로우 관계가 언제 생성되었는지 기록합니다.
  • Like 엔티티: 트윗에 대한 좋아요를 나타냅니다. user_id에는 좋아요를 누른 사용자의 ID를, tweet_id에는 좋아요를 받은 트윗의 ID를 저장합니다. created_at은 좋아요를 누른 시점을 기록합니다.
  • Retweet 엔티티: 트윗의 리트윗을 나타냅니다. 원본 트윗의 ID는 tweet_id에 저장되며, 리트윗한 사용자의 ID는 retweeted_by_user_id에 기록됩니다. created_at은 리트윗이 발생한 시점을 나타냅니다.
  • DirectMessage 엔티티: 사용자 간의 대화를 나타냅니다. 메시지의 고유 ID는 message_id, 발신자는 sender_id, 수신자는 recipient_id에 저장됩니다. 메시지 내용은 content로 기록하며, created_at은 메시지가 전송된 시점을 나타냅니다.

11.4 시스템 규모 산정

서비스 규모

  • 전체 사용자 수: 1억 명
  • 하루 평균 활성 사용자 수: 2000만 명
  • 사용자 1인당 하루 평균 트윗 생성 수: 5개
  • 트윗당 평균 크기: 200바이트
  • 전체 트윗의 20%는 미디어(평균 크기 1MB)를 포함
  • 트윗 보관 기간: 5년

저장소 규모

  • 트윗 저장소

    • 일별 트윗 저장 용량: 하루 활성 사용자 2000만 명×1인당 5개 트윗×트윗당 200 바이트 = 20GB/일
    • 연간 트윗 저장 용량: 20GB/일×365일 = 7.3TB/년
    • 5년간 트윗 저장 용량: 7.3TB/년×5년 = 36.5TB
  • 미디어 저장소

    • 일별 미디어 저장 용량: 하루 활성 사용자 2000만 명×1인당 5개 트윗×20% 미디어 포함 트윗×미디어 크기 1MB = 200TB/일
    • 연간 미디어 저장 용량: 200TB/일×365일 = 73PB/년
    • 5년간 미디어 저장 용량: 73PB/년×5년 = 365PB
  • 사용자 저장소(프로필 사진, 소개글 등을 포함하여 1인당 1MB로 가정)

    • 전체 사용자 저장 용량: 1억 명×1MB/사용자 = 100TB
    • 전체 저장 용량
      • 트윗 저장소: 36.5TB
      • 미디어 저장소: 365PB
      • 사용자 저장소: 100TB
      • 합계: 36.5TB + 365PB + 100TB ≈ 365PB
  • 대역폭

    • 일별 트윗량: 하루 활성 사용자 2000만 명×1인당 5개 트윗×평균 팔로워 100명 = 100억 건/일
    • 일별 대역폭: 100억 건/일×트윗당 200바이트 = 2TB/일
  • 미디어 전달에 필요한 일별 대역폭

    • 일별 미디어 전송량: 하루 활성 사용자 2000만 명×1인당 5개 트윗×20% 미디어 포함 트윗×평균 팔로워 100명 = 20억 건/일
    • 일별 미디어 대역폭: 20억 건/일×1MB/미디어 = 2PB/일
    • 총 하루 대역폭: 트윗 전송 2TB/일 + 미디어 전송 2PB/일 ≈ 2PB/일
  • 처리 요구 사항

    • 초당 최대 트윗 수: 일별 활성 사용자 2000만 명×1인당 5개 트윗 ÷ 일별 86,400초 ≈ 초당 1200건
    • 초당 최대 미디어 업로드 수: 초당 트윗 1200건×20% 미디어 포함 트윗 ≈ 초당 240건
    • 타임라인 생성을 위한 팬아웃 요청: 평균 팔로워 100명×초당 트윗 1200건 ≈ 초당 12만 건
  • 캐시 크기

    • 일별 트윗 조회 수: 일별 활성 사용자 2000만 명×1인당 하루 평균 타임라인 100번 조회 = 20억 건/일
    • 캐시 크기: 하루 20억 건×캐시 적중률 80%×트윗당 200바이트 = 약 320GB

11.5 고수준 설계 탐구

image

Figure 11.2: High-level system design of Twitter

  • 클라이언트-서버 아키텍처
  • 로드 밸런서
  • API 게이트웨이

11.5.1 마이크로서비스 아키텍처

트윗 서비스

  • 트윗 생성, 조회, 삭제를 처리합니다.
  • 트윗 데이터를 데이터베이스에 저장하고, 미디어 파일은 객체 저장소에 보관합니다.
  • 새로운 트윗을 메시지 큐에 전달하여 다른 서비스가 처리할 수 있도록 합니다.

사용자 서비스

  • 사용자 등록, 인증, 프로필 정보를 관리합니다.
  • 사용자 데이터를 데이터베이스에 저장합니다.
  • 팔로우와 언팔로우 기능을 처리하며, 팔로워-팔로잉 관계를 유지합니다.

타임라인 서비스

  • 사용자가 팔로우한 계정의 트윗을 모아 타임라인을 생성하고 제공합니다.
  • 메시지 큐에서 새로운 트윗을 받아 사용자 타임라인을 최신 상태로 업데이트합니다.
  • 타임라인 데이터를 캐시에 저장하여 빠르게 조회할 수 있도록 처리합니다.

검색 서비스

  • 키워드, 해시태그, 기타 조건을 기준으로 트윗 및 사용자를 검색할 수 있도록 합니다.
  • 트윗과 사용자 데이터를 효율적으로 검색할 수 있도록 인덱싱합니다.
  • 검색 결과를 연관성이나 인기도에 따라 순위별로 정렬하여 제공합니다.

서비스 성능을 높이고 확장성과 안정성을 확보하려면 여러 마이크로서비스에서 재사용할 수 있는 공통 소프트웨어 모듈과 기능을 만들어야 합니다.

  • 캐싱: 레디스 같은 분산 캐싱 레이어를 사용하면 백엔드 서비스의 부하를 줄이고 성능을 끌어올릴 수 있습니다.
  • 데이터베이스: 아파치 카산드라나 아마존 DynamoDB 같은 분산 데이터베이스를 사용하여 트윗, 사용자 정보, 팔로우, 좋아요, 리트윗 등 정형 데이터를 저장합니다.
  • 객체 저장소: 이미지와 동영상 등 미디어 파일은 아마존 S3 같은 객체 저장소에 보관합니다.
  • 메시지 큐: 마이크로서비스 간 비동기 통신을 위해 아파치 카프카 같은 메시지 큐를 사용합니다.
  • 실시간 업데이트: 웹소켓(WebSocket)을 사용하면 사용자가 실시간으로 업데이트를 받을 수 있도록 클라이언트와 서버를 연결할 수 있습니다.
  • 모니터링 및 로깅: 프로메테우스나 그라파나 같은 도구를 사용하여 요청 지연 시간, 오류율, 자원 사용량 등 주요 지표를 수집하여 시각화하는 것도 가능합니다.
  • 보안 및 프라이버시

11.6 트윗 서비스 설계

image

Figure 11.3: High-level architecture of Tweet Service

  • POST /tweets: 새로운 트윗 생성
    • 요청 본문: 트윗 내용, 사용자 ID, 미디어 첨부 파일(옵셔널)
    • 응답: 새로 생성한 트윗 객체(트윗 ID와 타임스탬프 포함)
  • GET /tweets/{tweetId}: 특정 트윗 조회(ID 기반)
    • 응답: 트윗 객체(트윗 내용, 사용자 정보, 타임스탬프, 좋아요와 리트윗 같은 활성 지표 포함)
  • DELETE /tweets/{tweetId}: 트윗 삭제(ID 기반)
    • 요청: 사용자 인증 토큰(토큰 작성자만 삭제할 수 있도록)
    • 응답: 성공 또는 오류 메시지
  • GET /users/{userId}/tweets: 특정 사용자가 작성한 트윗 조회
    • 요청: 사용자 ID, 페이지 매개변수(옵셔널)
    • 응답: 사용자가 작성한 트윗 목록

11.6.1 데이터 저장소

  • 데이터베이스(아파치 카산드라, 아마존 DynamoDB 등): 트윗 ID(tweetId), 사용자 ID(userId), 트윗 내용(content), 타임스탬프(timestamp) 같은 내용을 하나의 데이터에 담아 관계형 데이터베이스에 저장할 수 있습니다. 데이터가 각 노드에 고르게 분산되도록 파티션 키는 트윗 ID로 설정하며, 시간 순서대로 트윗을 효율적으로 조회하려고 클러스터링 키로 타임스탬프를 사용합니다.
  • 객체 저장소(아마존 S3 등): 트윗에 첨부된 이미지나 동영상 등 미디어 파일은 객체 저장소에 개별 파일로 저장합니다.

11.6.2 트윗 생성 과정

image

Figure 11.4: Tweet creation flow

11.6.3 트윗 조회 과정

image

Figure 11.5: Tweet retrieval flow

11.6.4 캐싱

트윗을 더 빠르게 조회하려면 트윗 서비스에서 레디스 같은 캐싱 시스템을 활용합니다.
예를 들어 인기 급상승 트윗이나 화제가 되는 트윗처럼 자주 요청하는 데이터를 캐시에 미리 저장해 두는 것이지요.

캐싱 전략

  • 시간 기반 슬라이딩 윈도우 캐싱
    • 최근 N시간(예 24시간) 이내에 게시된 트윗을 캐시에 유지합니다.
    • 새로운 트윗이 추가되면 캐시에 저장하고, 지정된 시간을 초과한 트윗은 캐시에서 삭제합니다.
  • 인기도 기반 캐싱
    • 좋아요, 리트윗, 댓글 같은 사용자 반응 데이터를 활용하여 트윗 점수를 계산합니다.
    • 점수가 일정 기준을 넘는 트윗만 캐시에 저장합니다.
  • 하이브리드 캐싱
    • 시간 기반과 인기도 기반을 함께 활용하는 방식입니다.
  • 예측 기반 캐싱
    • 머신러닝 모델을 활용하여 어떤 트윗이 인기를 끌 가능성이 높은지 예측합니다.
  • 사용자 기반 캐싱
  • 팔로워 수가 많거나 공식 계정으로 확인된 사용자가 올린 최신 트윗을 캐시에 저장합니다.

저장된 데이터를 잘 정리할 수 있는 전략

  • LRU(Least Recently Used)
    • 캐시 용량이 가득 차면 가장 오랫동안 사용하지 않은 트윗부터 삭제합니다.
  • TTL(Time To Live)
    • 트윗마다 유효 기간을 설정합니다.
    • 유효 기간을 초과한 트윗은 캐시에서 제거합니다.
  • LFU(Least Frequently Used)
    • 캐시 안에서 트윗을 얼마나 자주 조회하는지 추적합니다.
    • 캐시가 가득 차면 조회 빈도가 낮은 트윗부터 삭제합니다.
  • 크기 기반 삭제
    • 캐시의 최대 크기를 정해 둡니다(예 10GB).
    • 캐시가 이 한도에 도달하면 트윗 크기와 함께 LRU나 LFU처럼 다른 방식과 조합하여 삭제할 대상을 결정합니다.
  • 우선순위 기반 삭제
    • 사용자의 영향력, 트윗의 영향력(예 좋아요, 리트윗), 작성 시점 등 요소를 기준으로 트윗에 우선순위를 매깁니다.

직접 구현할 때도 여러 가지를 고려해야 합니다.

  • 캐시를 여러 계층으로 나누어 효율성을 높입니다.
    • 핫 캐시(hot cache)는 매우 자주 조회하는 트윗
    • 웜 캐시(warm cache)는 중간 빈도로 조회하는 트윗
    • 콜드 캐시(cold cache)는 거의 조회하지 않는 트윗
  • 시스템을 재시작할 때를 대비하여 사람들이 곧바로 자주 조회할 가능성이 높은 트윗을 미리 캐시에 채워 넣는 방법(캐시 워밍(cache warming))
  • 트윗이 수정되거나 삭제될 때 캐시에 남아 있는 데이터를 제대로 정리하려면 캐시 버전 관리(cache versioning)나 캐시 생성 번호를 사용하는 방법을 활용하는 것도 좋습니다.
  • 트윗 내용, 사용자 프로필, 타임라인 같은 데이터 유형별로 별도의 캐시를 운용하는 방식도 고려해 볼 만합니다. 이렇게 하면 데이터 유형에 맞는 최적의 캐싱 전략을 적용할 수 있습니다.
  • 모니터링으로 사용 패턴을 분석하고 이를 바탕으로 캐싱 전략을 지속적으로 개선해 나가야 합니다.

11.7 사용자 서비스 설계

image

Figure 11.6: High-level architecture of User Service

  • POST /users: 새로운 사용자 계정 생성
    • 요청 본문: 사용자 이름, 이메일, 비밀번호 등 사용자 정보
    • 응답: 새로 만든 사용자 객체 정보와 사용자 ID
  • GET /users/{userId}: 특정 사용자의 프로필 정보 조회
    • 응답: 사용자 이름, 소개, 프로필 사진 URL, 팔로워 및 팔로잉 수 등 프로필 정보를 포함한 사용자 객체
  • PUT /users/{userId}: 사용자 프로필 정보 수정
    • 요청 본문: 수정할 사용자 정보(예 소개, 프로필 사진 URL, 위치 정보 등)
    • 응답: 수정한 사용자 객체
  • POST /users/{userId}/follow: 다른 사용자를 팔로우
    • 요청: 사용자 인증 토큰과 팔로우하려는 대상 사용자 ID
    • 응답: 성공 또는 오류 메시지
  • DELETE /users/{userId}/follow: 다른 사용자를 언팔로우
    • 요청: 사용자 인증 토큰과 언팔로우하려는 대상 사용자 ID
    • 응답: 성공 또는 오류 메시지
  • GET /users/{userId}/followers: 특정 사용자를 팔로우하고 있는 사용자 목록 조회
    • 응답: 팔로워를 나타내는 사용자 객체 목록
  • GET /users/{userId}/following: 특정 사용자가 팔로우하고 있는 사용자 목록 조회
    • 응답: 팔로잉 중인 사용자를 나타내는 사용자 객체 목록

11.7.1 데이터 저장소

  • 사용자 테이블: 사용자 ID, 사용자 이름, 이메일, 비밀번호, 자기소개, 프로필 사진 URL, 위치 정보, 가입 일자 등 사용자 정보를 저장합니다. 이 테이블은 사용자 ID를 기본 키로 사용하여 데이터를 빠르게 조회합니다.
  • 팔로우 테이블: 이 테이블은 팔로워와 팔로잉 관계를 저장합니다. 팔로워 ID, 팔로잉 ID, 타임스탬프를 담는 컬럼으로 구성되어 있습니다. 팔로워 ID와 팔로잉 ID를 복합 기본 키(composite primary key)로 설정하여 관계의 고유성을 보장하며, 쿼리가 효율적으로 처리될 수 있도록 합니다.

11.7.2 사용자 생성 과정

image

Figure 11.7: User registration flow

11.7.3 사용자 인증 과정

image

Figure 11.8: Authentication flow

11.7.4 팔로우/언팔로우 과정

image

Figure 11.9: Follow/unfollow flow sequence diagram

11.7.5 팔로워/팔로잉 목록 조회 과정

image

Figure 11.10: Retrieving followers/followees sequence diagram

11.8 타임라인 서비스 세부 설계

  • GET /timeline/{userId}: 사용자의 홈 타임라인 조회
    • 요청: 사용자 인증 토큰
    • 응답: 사용자의 타임라인을 나타내는 트윗 객체 목록
  • GET /timeline/{userId}/mentions: 사용자가 언급된 타임라인 조회
    • 요청: 사용자 인증 토큰
    • 응답: 사용자가 언급된 트윗 객체 목록

11.8.1 데이터 흐름

image

Figure 11.11: The data flow for creating a new tweet and updating followers’ timelines

11.8.2 타임라인 조회 과정

image

Figure 11.12: The timeline retrieval flow when a user requests their home timeline

멘션 타임라인

image

Figure 11.13: The mentions timeline process for handling and retrieving mentions

11.8.3 푸시 기반 업데이트

타임라인 서비스로 사용자 타임라인을 실시간으로 업데이트하려면 푸시 방식이 효과적입니다.
새로운 트윗이 작성되면 타임라인 서비스가 웹소켓을 사용하여 관련 사용자에게 바로 알림을 보냅니다.

이 설계를 기반으로 타임라인 서비스는 팔로우한 사용자의 트윗을 모아 사용자 타임라인을 효율적으로 생성하고 제공할 수 있습니다.

11.9 검색 서비스 세부 설계

image

Figure 11.14: Search Service low-level design

  • GET /search/tweets?q={query}&limit={limit}&offset={offset}
    • 요청: 검색어와 함께 limit(옵셔널), offset(옵셔널)을 매개변수로 전달
    • 응답: 검색어와 일치하는 트윗 객체 목록
  • GET /search/users?q={query}&limit={limit}&offset={offset}
    • 요청: 검색어와 함께 limit(옵셔널), offset(옵셔널)을 매개변수로 전달
    • 응답: 검색어와 일치하는 사용자 목록을 반환

11.9.1 데이터 흐름과 인덱싱

image

Figure 11.15: Data flow and indexing sequence diagram

11.9.2 검색 쿼리 처리 과정

image

Figure 11.16: Search query processing sequence diagram

11.9.3 관련 점수와 순위 매기기

검색 서비스는 엘라스틱서치 기능을 활용하여 검색 결과의 관련성을 평가하고 순위를 매깁니다.
검색어와 문서 간의 연관성을 점수로 계산하고자 단어의 등장 빈도(Term Frequency, TF), 문서 내 중요도를 나타내는 역문서 빈도(Inverse Document Frequency, IDF), 특정 필드에 더 높은 가중치를 주는 필드 부스팅 방식 등을 종합적으로 사용합니다.
이런 점수는 검색 결과가 사용자에게 표시되는 순서를 결정합니다.

11.10 기타 고려 사항

  • 인기 주제와 해시태그 관리: 트렌드가 되는 주제와 해시태그를 추적하고 파악하려면 이들의 인기도와 사용 빈도를 분석하는 시스템이 필요합니다. 아파치 스톰(Apache Storm)이나 아파치 플링크(Apach Flink) 등 실시간 데이터 처리 도구를 활용하면 새롭게 들어오는 트윗 데이터를 실시간으로 분석하여 인기 주제를 빠르게 갱신할 수 있습니다.
  • 속도 제한과 트래픽 조절 구현: 사용자 수백만 명을 지원하는 대규모 시스템에서는 시스템 남용을 방지하고 리소스를 효율적으로 관리하는 데 속도 제한과 트래픽 조절 메커니즘이 반드시 필요합니다. 이를 위해 각 API 엔드포인트의 예상 사용 패턴과 시스템 용량에 따라 적절한 속도 제한을 설정해야 합니다.

Metadata

Metadata

Assignees

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions