Zettelkasten

Scheduler Job은 처리 시간을 고려해 중첩 실행을 방지해야 한다

·수정 2026.04.23·수정 2

요약

  • Scheduler job은 처리 시간을 반드시 고려해야 한다
  • 이전 job이 끝나기 전에 다음 스케줄이 실행되면 중복 처리, 리소스 경합이 발생한다

본문

Job 중첩 실행 문제

  • 이전 job이 안 끝났는데 다음 스케줄이 트리거되면 문제 발생
  • 동일 데이터 중복 처리
  • DB 커넥션, 메모리 등 리소스 경합

해결 방법

Lock 기반

  • 분산 락(Redis, DB lock)으로 중복 실행 방지
  • job 시작 시 락 획득, 종료 시 해제

DB Unique Constraint로 유저별 단일 Job 보장

  • (user_id, status) unique constraint + started_at 컬럼으로 timeout 관리
  • 이력 보존이 필요하면 Partial Index 활용
  • 좀비 레코드 방지: 주기적으로 started_at이 오래된 running 상태 정리 필요

프레임워크 설정

  • Quartz: @DisallowConcurrentExecution
  • Spring: fixedDelay vs fixedRate 구분
    • fixedRate: 이전 실행과 무관하게 고정 간격으로 실행
    • fixedDelay: 이전 실행 완료 후 간격을 두고 실행
  • RQ (Redis Queue):
    • job_timeout: job 최대 실행 시간 설정 (기본 180초)
    • ttl: 결과 보관 시간
    • failure_ttl: 실패한 job 보관 시간
    • depends_on: job 간 의존성 설정으로 순차 실행 보장
    • RQ-Scheduler: interval 기반 반복 실행 시 이전 job 완료 여부 체크 안 함 → 별도 락 필요

상태 체크

  • job 시작 전 이전 실행 상태 확인
  • 실행 중이면 skip 또는 대기

스케줄 간격 설정

  • 평균 처리 시간 + 버퍼를 고려해서 간격 설정
  • 처리량이 가변적이면 fixedDelay 방식이 안전

타임아웃 설정

  • 무한 대기 방지를 위한 job 타임아웃 필수
  • 타임아웃 발생 시 알림 + 후속 처리 로직 필요

참고