스프링

상품 주문 통계 배치 작업 강의 대본

148june 2025. 6. 19. 11:42

상품 주문 통계 배치 작업 강의 대본

🎯  개요 

안녕하세요! 오늘은 Spring Batch를 활용한 상품 주문 통계 배치 시스템에 대해 설명드리겠습니다.

여러분들도 실무에서 이런 경험 있으실 거예요. "매일 쌓이는 주문 데이터를 어떻게 효율적으로 통계로 만들까?" 오늘 소개할 시스템이 바로 그 해답입니다.

이 배치 시스템의 핵심은 조건부 실행입니다. 평일에는 일일 통계만, 매월 1일에는 월별 통계까지 자동으로 생성하는 똑똑한 시스템이죠.


📋 전체 구조 개요 

실행 패턴 소개

먼저 이 배치가 언제, 어떻게 실행되는지 보겠습니다.

평일 실행 시나리오 (예: 1월 15일)

 
주문 데이터 읽기 → 상품 일일 통계 생성 → 관리자용 일일 통계 생성 → 종료

월 첫날 실행 시나리오 (예: 2월 1일)

 
주문 데이터 읽기 → 상품 일일 통계 생성 → 관리자용 일일 통계 생성 
→ 상품 월별 통계 생성 → 관리자용 월별 통계 생성 → 종료

보시다시피 월 첫날에만 추가 작업이 실행되는 조건부 실행 구조입니다.

데이터 변환 파이프라인

이 시스템의 데이터 흐름을 보면:

  1. 원시 주문 데이터(Order) → 상품별로 집계
  2. 상품 일일 통계 → 관리자가 보기 쉽게 가공
  3. 관리자용 일일 통계 → (월 첫날) 월별로 재집계
  4. 상품 월별 통계 → 관리자용 월별 통계 생성

각 단계마다 비즈니스 목적에 맞게 데이터를 변환하는 것이 핵심입니다.


🔧 단계별 상세 분석 

1단계: 상품 일일 통계 생성 (productStatDailyStep)

 
java
.chunk(1000, transactionManager)  // 1,000개씩 처리
.reader(reader)                   // Order 읽기
.processor(processor)             // ProductOrderStatDaily 변환
.writer(writer)                   // 저장

왜 1,000개 청크일까요?

  • 주문 데이터는 보통 대용량입니다
  • 메모리 효율성과 처리 속도의 균형점
  • 너무 크면 메모리 부족, 너무 작으면 오버헤드 증가

오류 처리 전략:

  • 재시도 3회: 일시적 네트워크 오류 등 대응
  • 스킵 5개: 데이터 품질 문제로 처리 불가능한 주문 허용
  • 지수 백오프: 1초 → 2초 → 4초 간격으로 재시도

2단계: 관리자 상품 일일 통계 생성

 
java
.chunk(100, transactionManager)   // 100개씩 처리

왜 청크 크기가 줄어들었을까요?

  • 1단계에서 이미 집계된 데이터라 양이 적음
  • 더 안정적인 처리를 위해 작은 청크 선택
  • 스킵 허용량도 1개로 줄임 (데이터 품질이 더 중요)

3단계: 조건부 실행 분기점 (FirstDayOfMonthDecider)

 
java
.next(firstDayOfMonthDecider)
.on(FIRST_DAY).to(productOrderStatMonthlyStep)
.on(NOT_FIRST_DAY).end()

핵심 설계 철학:

  • 매일 실행되지만 필요한 작업만 수행
  • 월별 통계는 매월 1일에만 생성
  • 시스템 리소스 효율적 활용

4-5단계: 월별 통계 생성 (월 첫날만)

월별 통계 생성 단계들은 일일 통계와 비슷하지만:

  • 더 작은 청크 크기 (100개)
  • 더 엄격한 오류 처리 (스킵 1개)
  • 월 단위 집계 로직 적용

🛡️ 안정성 및 성능 최적화 

오류 처리 전략

재시도 정책 (Retry Policy)

 
java
.retry(Exception.class)
.retryLimit(3)
.backOffPolicy(exponentialBackOffPolicy())

실무에서는 다양한 오류가 발생합니다:

  • 데이터베이스 일시적 연결 오류
  • 네트워크 타임아웃
  • 메모리 부족 등

지수 백오프를 사용하는 이유:

  • 시스템이 복구될 시간을 제공
  • 연속적인 재시도로 인한 시스템 부하 방지
  • 1초 → 2초 → 4초 (최대 30초)

스킵 정책 (Skip Policy)

 
java
.skip(Exception.class)
.skipLimit(5)  // 1단계
.skipLimit(1)  // 2-5단계

왜 단계별로 스킵 허용량이 다를까요?

  • 1단계: 원시 데이터라 품질 문제 가능성 높음
  • 2-5단계: 이미 검증된 데이터라 엄격한 기준 적용

성능 최적화

청크 크기 최적화:

  • 대용량 원시 데이터: 1,000개 (처리 속도 우선)
  • 집계 데이터: 100개 (안정성 우선)

트랜잭션 관리:

  • 청크 단위별 개별 트랜잭션
  • 부분 실패 시에도 전체 작업 영향 최소화

🎯 실무 적용 팁 

모니터링 포인트

  1. 실행 시간 모니터링
    • 일일 통계: 보통 30분 이내
    • 월별 통계: 2-3시간 소요 가능
  2. 오류율 추적
    • 스킵된 데이터 건수 확인
    • 재시도 발생 패턴 분석
  3. 데이터 품질 검증
    • 통계 결과 일관성 체크
    • 전일 대비 급격한 변화 감지

운영 시 주의사항

월 첫날 리소스 관리:

 
java
// 월 첫날에는 더 많은 메모리와 CPU 사용
// 인프라 스케일링 고려 필요

장애 대응 시나리오:

  • 1-2단계 실패: 해당 일자 재실행
  • 3-4단계 실패: 월별 통계만 별도 실행
  • 부분 실패: 스킵된 데이터 별도 처리

확장성 고려사항

수평 확장:

  • Reader를 파티셔닝하여 병렬 처리
  • 상품 카테고리별 분산 처리 가능

수직 확장:

  • 청크 크기 조정으로 메모리 사용량 최적화
  • 처리 성능과 안정성 균형점 찾기

🔍 질의응답 예상 질문 

Q1: 왜 월별 통계를 매월 1일에만 생성하나요? A: 월별 통계는 해당 월의 모든 일일 데이터가 필요합니다. 매월 1일에 전월 데이터를 기반으로 생성하는 것이 효율적이죠.

Q2: 배치 실행 중 장애가 발생하면 어떻게 되나요? A: Spring Batch의 JobRepository가 실행 상태를 추적합니다. 중단된 지점부터 재시작 가능하며, 청크 단위로 트랜잭션이 관리되어 부분 실패에도 안전합니다.

Q3: 성능 개선 방법은? A: 청크 크기 조정, 병렬 처리, 인덱스 최적화, 파티셔닝 등 다양한 방법이 있습니다. 데이터 특성에 맞는 최적화가 핵심입니다.


📝 마무리 

오늘 소개한 배치 시스템의 핵심은:

  1. 조건부 실행으로 리소스 효율성 확보
  2. 단계별 최적화된 청크 크기와 오류 처리
  3. 안정성성능의 균형
  4. 실무 적용 가능한 설계 패턴