ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [우아한테크토크] 선착순 이벤트 서버 생존기!
    세미나, 영상 요약정리 2022. 4. 28. 17:16
    728x90

    https://www.youtube.com/watch?v=MTSn93rNPPE 

     

    해당 영상을 보고 정리해본 글입니다.

     

    유래

    선착순 만명에게 치킨을 제공하는 이벤트를 실시했었습니다.

     

    유저의 반응 : 배민 또 장애 나겠네..

     

    장애가 발생한다면 사이드 이펙트

    - 이벤트 참가자 : 저녁 안먹고 기다렸는데 이럴거면 왜 하는거지?

    - 이벤트 비참가자 : 나는 이벤트 필요없고 다른 음식 시키려고했는데 왜 안되는거지?

    - 업주 : 광고비 냈는데, 오늘 매출은?

    - 개발자 : 멘붕

     

    목표

    순간적인 대량 트래픽을 소화하자

    이벤트에 영향없이 일반주문은 가능하도록 장애를 격리하자

     

     

    기존의 주문시스템

    장바구니 -> 주문준비(Validation 및 세션저장) -> 주문지면 -> 결제요청 -> 결제완료

    즉, 하나의 프로세스에 연계된 API들이 많음

    https://www.youtube.com/watch?v=MTSn93rNPPE

    이벤트 트레픽

    주말피크는 3천 RPM이 들어오고 이벤트 최고때는 47만 RPM이 들어옴(기존대비 150배)

     

    AWS를 사용하고 있으니 스케일업, 스케일아웃으로 대응할 수 있지 않을까?

    10배를 예상하고 준비를 해도 150배가 들어오면 장애가 발생

    결제를 위해서는 PG사가 존재함 ( PG사에서 장애가 발생할 수도 있음)

     

    해결방안

    처리할 수 있는 만큼만 순서대로 입장시키자 

     

    큐 시스템

    모든 이벤트 대상에게 번호표 발급

    번포효를 발급받은 사용자를 줄 세우기(대기열)

    대기열의 사용자에게 현재 몇번째 대기순서를 알려줌

    서버가 소화할 수 있을 만큼 사용자를 입장(참가열)

     

    고성능 처리 가능을 위해 Redis를 선택하여 처리

     

    Why Redis?

    많은 서비스에 사용된 검증된 저장소

    입/출력이 빠른 In-Memory DB

    다양한 자료구조를 지원했기 때문에 다양한 요구사항 처리 가능

     

    대기열 ( Redis의 Sorted Set 사용)

    이벤트 주문을 요청한 순서대로 처리 (ZADD - 데이터 추가시 부여한 스코어에 따라 정렬)

    대기중인 사용자에게 현재 대기순번을 제공(ZRANK - 현재 순위 조회)

    일정한 수만큼 대기열에서 참가열로 이동시키기 ( ZRANGE - 일정한 수만큼 리스트 조회)

     

    Redis 사용시 고려사항

    각 명령어의 시간복잡도를 확인

    잘 알려진 내용이지만 풀스캔을 하는 O(N) KEYS 명령어 사용 금지 - Redis는 싱글 스레드

    Sorted Set  : O(log(n))

     

    큐 시스템 플로우

    이벤트 주문 요청 -> 대기번호 생성 및 대기열 추가 -> (1초마다 설정된 값 만큼 대기열 -> 참가열으로 이동시킴) -> 참여자들은 이때 참가열진입까지 대기 -> 기존 주문 플로우

     

     

    이제는 10배의 트래픽이던 100배의 트레픽이 들어오던 큐 시스템을 활용하여 설정한 만큼 일정한 트래픽을 보낼 수 있게 되었습니다.

     

    큐 시스템을 만들긴 했는데 중간에 어떻게 끼워넣을까?

    기존에 주문 라우터가 존재했습니다. (주문 라우터의 역할)

    주문 시스템으로 요청이 들어오는 출입구

    RULE에 따라 API HOST를 변경할 수 있음

    RULE은 회원번호, 업소번호, 지역코드로 설정됨

    WebFulx + Netty로 이루어진 논블로킹 서버

    10000 TPS 거뜬히 처리가능

     

    주문 라우터가 요구사항을 충족했기 때문에 이를 활용하여 큐 시스템을 넣었습니다.기존의 주문 라우터는 요청에 들어있는 회원번호와 업소번호를 가지고 Rule을 확인합니다.그리고 Rule에 설정된 HOST로 라우팅해줍니다.만약 Rule에 없는 요청이 오면 기존서버를 타게됩니다.

    https://www.youtube.com/watch?v=MTSn93rNPPE
    여기에 개발을 추가하여 해결하였습니다.쿠폰 시스템에 큐를 붙이고 쿠폰이 발행될때마다 회원번호들을 Rule에 있는 회원LIST에 쭉 넣어줍니다.업소LIST는 요일별로 업소목록을 미리 받아서 할당해 둡니다.
    https://www.youtube.com/watch?v=MTSn93rNPPE

    이제 일반 사용하는 주문 프로세스를 그대로 가게되고 쿠본발급을받고 이벤트업소는 큐 시스템을 타고 가게 됩니다.

    https://www.youtube.com/watch?v=MTSn93rNPPE

    AWS를 사용하고 있기 때문에 주문 시스템을 복제해서 이벤트용 주문 시스템을 큐 시스템에 붙여놨습니다.

    https://www.youtube.com/watch?v=MTSn93rNPPE

    이제 드디어 이벤트용 주문에서 장애가 발생하더라도!

    일반 사용자는 영향을 받지 않습니다.

    https://www.youtube.com/watch?v=MTSn93rNPPE

     

    이제 큐 시스템을 이용하여 2가지 목표를 모두 해결하였습니다.

    순간적인 대량 트래픽을 소화하자

    이벤트에 영향없이 일반주문은 가능하도록 장애를 격리하자

     

    이벤트 모니터링

    CloudWatch 대시보드를 적극 활용하여 주요 서버/지표들을 모니터링프로모션 어드민을 만들어 대기열/참가열을 모니터링하고 각종 변수를 셋팅하면서 대응

     

    부하에 따라서 수치를 조절하면서 이벤트를 진행(대기열에서 몇개를 꺼내서 참가열로 넣을지)

     

     

    후기

    선착순 이벤트는 순간적으로 몰리는 TPS를 감당하기 어렵기 때문에 서버 개발자에게 매우 힘든 이벤트입니다.

    이를 해결하기 위한 큐 시스템이 있다는 것을 알게 되고 적용과정을 알게되어서 좋았습니다.

     

    댓글

Designed by Tistory.