Skip to content

[refactor][queue-srevice] 토큰 발급 스케줄러 부하 평탄화 및 N+1 해결 #37

Description

@rlaxxwls13

📌 개요

현재 토큰 발급 스케줄러(AdmissionScheduler)와 후보 조회 로직(findAdmissionCandidates)에 다음 세 가지 구조적 문제가 있습니다.

1. 부하 평탄화 부재

스케줄러가 5초 주기로 batchSize 명을 한 번에 발급하여, 토큰 발급 직후 N명이 동시에 주문 API를 호출하는 Thundering Herd가 발생합니다. 100ms × 18명 = 부하 10배 평탄화를 적용해 순간 동시 호출량을 줄여야 합니다.

2. N+1 패턴

findAdmissionCandidates가 ZRANGE 1회 + HGETALL N회(batchSize만큼)로 Redis를 호출합니다. 100ms 주기로 호출될 경우 RTT 누적이 스케줄러 실행 시간을 압박합니다.

  • batchSize=18 기준: 19회 Redis 호출
  • 활성 프로그램 5개 기준: 95회/cycle
  • RTT 0.5ms 가정 시 약 47.5ms 소모 (100ms 주기 중 절반)

3. 멀티 인스턴스 환경 미고려

@Scheduled만으로는 여러 인스턴스에서 동시 실행될 경우 같은 토큰이 중복 admit될 수 있습니다. 현재 단일 인스턴스 가정이지만 확장 가능한 구조로 보강이 필요합니다.

🎯 목표

  • 토큰 발급 주기 5000ms → 100ms 변경으로 부하 평탄화
  • 후보 조회를 Lua 스크립트로 일괄 처리하여 N+1 해소 (19회 → 1회)
  • ShedLock으로 멀티 인스턴스 환경에서 단일 리더 보장

🧩 리팩토링 범위

  • find_admission_candidates.lua 스크립트 작성
  • RedisQueueTokenRepository.findAdmissionCandidates() Lua 기반 재구현
  • AdmissionScheduler 주기 조정 (5s → 100ms, fixedDelay 사용)
  • ShedLock 의존성 추가 및 ShedLockConfig 작성
  • @SchedulerLock 어노테이션 적용
  • QueueProperties.admissionBatchSize 값 18로 설정

🏗️ 변경 설계

Before

  • @Scheduled(fixedRate = 5000) → 5초마다 batch 발급
  • findAdmissionCandidates: ZRANGE 1회 + HGETALL N회 (N+1 패턴)
  • 멀티 인스턴스 보호 없음

After

  • @Scheduled(fixedDelay = 100) + @SchedulerLock → 100ms마다 18명 발급
  • findAdmissionCandidates: Lua 스크립트로 ZRANGE + HMGET 일괄 1회 호출
  • ShedLock으로 전역 단일 리더 보장 (Redis 락 사용)

⚠️ 주의 사항

🧪 검증 방법

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions