[WebSocket & MessageQueue] 카카오톡 시스템 디자인

2 분 소요

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_9 59 07

[카카오톡 시스템 디자인 WebSocket 메시지 큐 SQL vs NoSQL](https://www.youtube.com/watch?v=VODXNECZOBQ)

Chat Server / API Server 나누기

  • WebSocket은 Open Connection을 유지해줘야 되기 때문에 따로 Chat Server 를 만들어서 관리
  • 일반적인 리퀘스트 (로그인 / 프로필 사진 바꾸기) 는 API Server 에서 HTTP 로 관리

메시지 큐 (Message Queue)

  • ex) Kafka, RabbitMQ
  • 서비스들 간에 데이터를 주고 받는 방법 중에 하나
  • 메시지 큐를 사용하지 않고 서비스간 데이터 통신 방법
    • RestAPI / RPC 를 사용하면 Synchronous(동기식) 하게 데이터를 주고 받음
  • 메시지 큐를 사용하면 Asynchronous(비동기식) 하게 데이터 처리
  • 두 가지 entity를 가짐
    • publisher: 이벤트가 일어났을 때 이벤트를 메시지 큐에 넣는 사람
    • subscriber: 이벤트가 일어나면 나한테 알려줘라고 메시지 큐한테 subscribe 하고 있는 서비스

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_10 08 39

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_10 08 55

장점

  • Decoupling
    • Service A가 Service B, C, D 모두에 Dependency가 생김
    • ex) Service A - Chat Server 유저가 메시지를 보낼 때(event) 데이터 베이스 저장(Service B), 메시지를 받는 유저한테 메시지 포워드 (Service C), 받는 유저가 지금 로그인해 있지 않는다면 푸시 노티피케이션 (Service D)

      %E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_10 21 39

    • synchronous 하게 하다보면 모든 디펜던시에 관련된 코드를 Service A에 넣어야 함
    • ⇒ Service A 는 점점 복잡, 테스트 어려워짐, 디펜더시가 많아짐(커플링이 많다)
    • ⇒ 시스템 디자인시 비효율적
    • 메시지 큐 적용시 디펜던시가 훨씬 적어짐
      • 각각의 서비스는 Message Queue만 알면 됨
        • Service A는 Service B, C, D가 존재한다는 사실을 몰라도 됨

        %E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_10 25 47

1 : 1 채팅 시스템 디자인

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_10 30 15

웹 서비스의 경우 로그인되어 있거나 로그아웃 되어있거나 똑같이 push notification을 해줘야 하는 것 같다. 왜냐하면, 웹 서비스에서 로그아웃한다고 push notification을 보내도 알 수 있는 것이 아니고 로그인되어 있어도 알림은 필요할 것 같다.

  • 로그인 되어 있는 유저들은 각각 챗 서버들 하고 WebSocket 으로 오픈 커넥션이 있음.
    1. 유저 A가 메시지를 써서 WebSocket을 통해 Chat Server 1로 전송
    2. 유저 B의 Queue에 메시지를 넣어준다.
    3. 유저 B의 Queue를 subscribe 하고 있었던 서비스들(Message DB, Chat Server 3)한테 연락이 감
    1. Message DB는 모든 큐에 subscribe
      1. DB에다 message를 저장, Chat Server 3이 메시지를 가져와서 유저 B한테 메시지 포워드

데이터 베이스 종류 선택 (SQL vs NoSQL)

  • 트래픽 특성
    • 엄청난 양의 트래픽 그룹 채팅 - 하루에 600억 메시지
    • 오래된 채팅 잘 안봄
    • Read / Write ratio 1 : 1 → 둘 다 효율적으로 되야함
  • 다른 데이터들과 join 할 필요가 거의 없음
  • Relational Database 같은 경우 데이터가 많아지고 index가 많아지면 느려짐
  • Key Value Store
    • 스케일 하기가 편함
    • Read Latency 가 낮음
    • Facebook 같은 경우 HBase; 디스코드는 Cassandra를 사용함
  • Key 를 만들때 Range Scan 하기 쉽게 디자인 해야함
    • 최근에 보낸 메시지일 수록 Key 값이 높게
    • 메시지 아이디가 계속 올라가는 방식

그룹 챗 기능 추가

  • 그룹 챗 몇명까지 지원 할 거냐에 따라 디자인이 달라질 수 있음
  • 그룹 챗 최대 200명까지 지원한다고 가정을 한다면
    • 어느정도의 Fan out은 괜찮음

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-10-15_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_11 06 12

  1. 유저 A가 챗 서버에 메시지를 보낸다.
  2. 챗 서버가 그룹에 어떤 멤버들이 있는지 그룹 챗 DB에 물어본다.
    • Group Chat DB : Relational DB
  3. 그룹에 누가 있는지 응답을 받았다면 받아야할 유저들의 Queue에 chat Server가 메시지를 넣어준다.
  4. 이 후 동일

카테고리:

업데이트: