tonykang22 / chat

0 stars 0 forks source link

채팅 서비스 레퍼런스 분석4. Slack Architecture #2

Open tonykang22 opened 1 year ago

tonykang22 commented 1 year ago

Slack Architecture



Slack 1.0


기능 요구 사항

  1. 채널 내에서 메시지를 보낼 수 있어야 한다.
  2. 메시지는 시간 순이며 언제든 다시 조회할 수 있어야 한다.


비기능 요구 사항

  1. 낮은 latency
  2. 높은 신뢰성
  3. 매일 400만 명의 접속자, 최대 250만 명이 동시에 접속 예상
  4. 400만 명이 하루에 최소 10시간 동안 연결 상태 유지 예상


디자인

image


구성

  1. Client
    • 웹, 모바일, 데스크탑
  2. Message Server
    • Backend Server의 업데이트 내용을 수신, 워크스페이스 내의 모든 클라이언트에게 실시간 이벤트 전송
  3. Backend Server
    • Slack의 주요 로직 수행
      • User, Workspace, Channel이 무엇이고 어떻게 상호작용하는지 알고 있다.
  4. MySQL DB
    • 발생하는 모든 작업을 위한 스토리지 계층



동작 원리


  1. Princess는 FinApp의 최신 스냅샷을 가져오기 위해 Backend를 호출하는 클라이언트를 연다.
    • 이 스냅샷은 컴퓨터의 RAM에 로컬로 저장
      • 스냅샷 에는 워크스페이스 내의 모든 채널, 그룹, 사용자, 메시지 등에 대한 정보가 포함
    • Lekan도 마찬가지
  2. 스냅샷 외에도 Backend Server는 메시지 서버의 URL도 반환한다.
    • Lekan과 Princess의 클라이언트는 Message Server에 연결
    • Lekan & Princess의 클라이언트는 이 WebSocket 연결을 통해 FinApp 내의 모든 이벤트에 대한 업데이트를 수신
      • 100개 이상의 이벤트 유형이 WebSocket 연결을 통해 발생
  3. Princess가 FinApp 내 채널인 #standup에 Lekan을 언급하는 메시지를 입력하고 전송한다.
    • Enter를 클릭하면 클라이언트가 /message Backend Server에 POST 요청 전송
  4. Backend Server는 메시지를 MySQL 데이터베이스에 저장하고, Princess 클라이언트에게 확인 메시지를 전달한다.
    • 이후 메시지는 프린세스에게 "delivered"으로 표시
    • 실패하는 경우 Princess는 클라이언트에게 "retry" 옵션이 표기
  5. Backend Server는 new_msg Princess의 메시지가 포함된 이벤트를 Message Server로 보낸다.
  6. Message Server는 new_msg 이벤트를 수신하여 처리하고 FinApp의 모든 사용자에게 메시지를 팬아웃한다.
    • Lekan는 고객에게 메시지를 보낸 후에 메시지를 읽을 수 있다.



예측


  1. Message Server는 하루에 최대 500,000 개의 연결을 허용할 수 있다.
    • 500,000 개 동시 연결 가능
    • 4M을 예상하기 때문에 8 개의 메시지 서버 필요
  2. 각 사람은 하루에 50 개의 메시지를 보내므로 Backend Server, Message Server 및 MySQL Server는 하루에 2억개의 메시지 요청을 받는다.
  3. Workspace의 평균 크기는 8k이다.
    • 하나의 메시지가 workspace에 전송될 때, Message Server가 최소 8,000번 (각 클라이언트 마다 하나씩) 보낼 것으로 예상
  4. 하나의 MySQL 서버가 20M/일 처리 가능하다고 가정할 때, 2억개의 요청을 예상하므로 10개의 인스턴스가 필요하다.


image



Slack 2.0



이슈



개선 방안 1. Fat + Lazy 클라이언트

image



개선 방안 2. Flannel

image


  1. Flannel은 쿼리 엔진으로 요청에 응답하고 캐시로서 응답을 제공할 수 있다.
  2. Flannel은 캐시로 활용된다.
    • Flannel을 통해 RAM에 데이터를 저장할 수 있다.
    • Flannel은 쓰기 기능에는 사용되지 않는다.
      • Write-around 전략을 사용한다.



잠깐 : Write-around 전략?



두 가지 경로

  1. Client -[HTTP] - BackendServer
    • Backend의 모든 호출이 Flannel을 통해 이뤄진다.
    • 비용이 많이 드는 요청 결과는 캐시할 수 있다.
      • 불필요한 요청을 줄일 수 있다.
  2. Client -[WebSocket]- MessageServer
    • Client가 local 스냅샷을 업데이트하기 위한 경로
      • Client가 업데이트할 때, Flannel에 해당 스냅샷을 업데이트 해둬서 다른 Client에게도 전달 가능



개선 방안 3. Flannel Reloaded



Distributed Flannel

image



Query Engine



Preemptive Updates

image




그 외

  1. Memcache 혹은 Redis를 캐시로 사용하지 않고 Flannel을 사용한 이유는 무엇인가?
    • A1: Flannel은 쿼리 엔진의 기능도 있기 때문이다.
  2. Flannel은 읽기 전용인가?
    • A2: 그렇다.
  3. Workplace와 DB 샤드는 1:1 매핑되어 있는가?
    • A3: 그렇지 않다. DB 서버 샤드는 하나가 아닌 다양한 workplace를 처리한다.