회고

항해플러스 8주차 회고

반응형

이번 주차는 콘서트 프로젝트를 진행하면서 대기열을 기존에는 RDB를 사용하여 구성하였으면, REDIS를 사용해서 구현하기 위해 다시 설계하고 구현해 보는 시간을 가졌다.

대기열 리팩토링

대기열은 기존에 동시성 유즈 케이스 고민하면서 사용했던 Redisson 라이브러리를 활용해서 Redis를 사용했다.

대기열은 두 가지 상태를 가지고 있으며, 서비스 이용을 위해 대기하거나, 서비스를 이용할 수 있고, 대기열 만료 시간이 지난 사용자는 대기열에서 삭제가 되기 때문에 별도의 상태를 관리하지 않는 구조로 설계 방향을 잡았다.

Wating Queue

redissonClient.getScoredSortedSet("waitQueue");

  • Redis Sorted Set 자료 구조를 기반으로 만들어진 RScoredSortedSet 사용
  • waitQueue.add(System.currentTimeMillis(), userId); Key는 userId, Score는 요청 시간을 저장
  • add 명령어는 내부적으로 Redis ZADD 명령어로 신규 대기열을 추가하고, RANK 대기열 순번을 반환
  • 대기열에 이미 존재하는 사용자가(활성화되지 않은 사용자)가 대기열을 다시 신청하는 경우 순번은 맨 뒤로 밀리게 됩니다.

Ongoing Queue

redissonClient.getMapCache("ongoingQueue");

  • Redis Hash 자료 구조를 기반으로 만들어진 RMapCache 사용
  • Hash와 차이점은 Hash는 개별 요소 대해 TTL 설정이 불가능 하지만, RMapCache는 개별 요소에 대해 TTL 사용이 가능하다.(대기열 만료시간)
  • 콘서트 최종 결제가 성공한 사용자는 OngoingQueue에서 제거

대기열 활성화 스케쥴러

  • 스케쥴러를 통해서 QUEUE_LIMIT - iQueueRedisRepository.getOngoingCount() 대기열 진입 가능한 수 계산
  • 대기열 진입 가능 한 수만큼 waitQueue.pollFirst(availableQueueCount). stream(). toList(); poll() -> 내부적으로 Redis ZRANGE 명령어를 사용해서 1번째 순번부터 availableQueueCount까지 삭제
  • waieQueue에서 삭제된 userId들을 OngoingQueue로 삽입하며 대기열 만료 시간만큼 활성화

대기열 설계 방향성 선정 과정

  1. 대기열 활성화의 경우 TTL 없이 OngoingQueue에서 만료된 토큰의 수만큼 WaitingQueue에서 전환되는 경우
  • 서비스를 이용할 수 있는 사용자를 항상 일정 수 이하로 유지할 수 있다는 장점이 있지만
  • 서비스를 이용하는 사용자의 액션 하는 속도에 따라 대기열의 전환시간이 불규칙하다는 단점이 있다.
  1. N초마다 M개의 토큰을 OngoingQueue로 전환하는 경우
  • 대기열 고객에게 서비스 진입 가능 시간을 대체로 보장할 수 있지만
  • 서비스를 이용하는 사용자의 수가 보장될 수 없다.

첫 번째 방식에서 가장 큰 문제점인 앞사람이 완료하지 않으면 뒷사람이 들어갈 수 없는 문제를 해결하기 위해 각 사용자에 대하여 평균적인 시간(한 유저가 콘서트 조회를 시작한 이후에 하나의 예약을 완료할 때까지 걸리는 시간)을 고려하여 대기열 만료시간을 설정, 두 번째 방식에서 적절한 동시 접속자를 유지하기 위해서 서버 트래픽의 최대치를 고려하여 QUEUE_LIMIT로 동시 접속자 제한을 두어 처리하는 방향으로 1번과 2번 케이스에 대한 장단점을 최대한 살려서 가져가는 방식으로 설계를 진행했다. 

 

Redis Hash는 기본적으로 개별 요소에 대한 TTL 설정이 불가능하기 때문에 내가 설계한 방향대로 구현하기 위해서 각 사용자마다 Hash를 생성해서 그 Hash에 대한 TTL을 걸어줘야 하는데, Hash를 생성하는 만큼 Redis에 대한 부하가 많이 심해질 거라고 예상이 되기 때문에 순수 Redis를 사용하는 경우에는 어떤 식으로 설계할지 고민해봐야 될 것 같다.

 

Redisson에서 제공해 주는 RMapCache는 개별 요소에 대한 TTL을 어떤 식으로 제공을 하는 건지 공부를 해봐야 할 것 같고, 순수 Redis를 사용하는 경우에는 어떤 식으로 설계할지 고민이 필요해 보인다.

반응형

'회고' 카테고리의 다른 글

항해 플러스 4기 백엔드 솔직 후기  (1) 2024.06.02
항해 플러스 9주차 회고  (0) 2024.05.19
항해 플러스 5주차 회고  (0) 2024.04.20
콘서트 예약 프로젝트 회고  (0) 2024.04.18
항해 플러스 4주차 회고  (0) 2024.04.13