Skip to content

접속자 대기열

thing-zoo edited this page Mar 17, 2024 · 4 revisions

도입이유

대규모 트래픽으로 인한 DB 부하를 줄이고 UX을 높이기 위해

1차 문제상황

수강신청 시, 대규모 트래픽으로 인해 DB 부하 및 대기 시간에 대한 처리 필요

해결 방안

  1. Kafka: 미들웨어를 활용한 정확한 메세지 큐 시스템 구성 가능
  2. Redis: Sorted Set을 활용하면 score 기준으로 정렬이 가능하고, Queue처럼 사용 가능

의견 조율

  1. Kafka는 단일 파티션이 아니라면 순서 보장이 불가능, 구축 경험이 없어 시간적 비용이 큼
  2. Redis는 빠른 속도를 자랑하고 구축 경험이 있어 비교적 시간적 비용이 작지만 안정성 문제가 있음

의견 결정

대규모 데이터 스트리밍 및 이벤트 처리를 위해 내구성, 확장성 및 내결함성이 뛰어난 메시지 대기열이 필요한 경우 Kafka가 적합하겠지만, 적은 대기 시간, 단순성 및 실시간 응답성을 우선시하여 Redis가 더 적합하다 판단

2차 문제상황

수강 신청 요청과 응답을 분리하게 되면서 서버에서 클라이언트로 따로 응답을 보내줘야함

해결 방안

  1. Long Polling: 서버에서 접속 시간을 길게 하는 방식
  2. SSE(Server-Sent-Event): 서버의 데이터를 실시간, 지속적으로 Streaming하는 기술
  3. Websocket: 양방향 채널을 이용한 실시간 양방향 통신

의견 조율

  1. Long Polling: 다수의 클라이언트에게 동시에 이벤트가 발생될 경우에는 서버의 부담이 급증
  2. SSE(Server-Sent-Event): 가볍고 구현하기 쉽지만, 최대 동시 접속 수가 제한이 있음
  3. Websocket: 최대 동시 접속 수가 제한이 없고 stomp를 사용하면 pub/sub 모델 사용 가능

의견 결정

동시 접속자가 많이 몰릴 수 있으므로, websocket & stomp를 사용해 각 클라이언트별 응답을 구독해둔 후 실시간으로 메세지를 보내주는 방식을 선택

문제 해결

image

  1. 수강신청 요청이 오면 Redis의 Sorted Set(대기열)에 요청(key: 수강신청, value: 요청내용, score: 시간)을 저장
  2. 스케쥴링
    1. 500ms마다 대기열에서 zrange 명령어를 통해 100개씩 정보를 가져와 수강신청 요청을 처리한 후 결과를 클라이언트로 전송
    2. 100ms마다 zrank 명령어를 통해 score(시간)에 대한 오름차순 순위(사용자의 대기순번)을 클라이언트로 전송
Clone this wiki locally