상품 주문 통계 배치 작업 강의 대본
상품 주문 통계 배치 작업 강의 대본
🎯 개요
안녕하세요! 오늘은 Spring Batch를 활용한 상품 주문 통계 배치 시스템에 대해 설명드리겠습니다.
여러분들도 실무에서 이런 경험 있으실 거예요. "매일 쌓이는 주문 데이터를 어떻게 효율적으로 통계로 만들까?" 오늘 소개할 시스템이 바로 그 해답입니다.
이 배치 시스템의 핵심은 조건부 실행입니다. 평일에는 일일 통계만, 매월 1일에는 월별 통계까지 자동으로 생성하는 똑똑한 시스템이죠.
📋 전체 구조 개요
실행 패턴 소개
먼저 이 배치가 언제, 어떻게 실행되는지 보겠습니다.
평일 실행 시나리오 (예: 1월 15일)
주문 데이터 읽기 → 상품 일일 통계 생성 → 관리자용 일일 통계 생성 → 종료
월 첫날 실행 시나리오 (예: 2월 1일)
주문 데이터 읽기 → 상품 일일 통계 생성 → 관리자용 일일 통계 생성
→ 상품 월별 통계 생성 → 관리자용 월별 통계 생성 → 종료
보시다시피 월 첫날에만 추가 작업이 실행되는 조건부 실행 구조입니다.
데이터 변환 파이프라인
이 시스템의 데이터 흐름을 보면:
- 원시 주문 데이터(Order) → 상품별로 집계
- 상품 일일 통계 → 관리자가 보기 쉽게 가공
- 관리자용 일일 통계 → (월 첫날) 월별로 재집계
- 상품 월별 통계 → 관리자용 월별 통계 생성
각 단계마다 비즈니스 목적에 맞게 데이터를 변환하는 것이 핵심입니다.
🔧 단계별 상세 분석
1단계: 상품 일일 통계 생성 (productStatDailyStep)
.chunk(1000, transactionManager) // 1,000개씩 처리
.reader(reader) // Order 읽기
.processor(processor) // ProductOrderStatDaily 변환
.writer(writer) // 저장
왜 1,000개 청크일까요?
- 주문 데이터는 보통 대용량입니다
- 메모리 효율성과 처리 속도의 균형점
- 너무 크면 메모리 부족, 너무 작으면 오버헤드 증가
오류 처리 전략:
- 재시도 3회: 일시적 네트워크 오류 등 대응
- 스킵 5개: 데이터 품질 문제로 처리 불가능한 주문 허용
- 지수 백오프: 1초 → 2초 → 4초 간격으로 재시도
2단계: 관리자 상품 일일 통계 생성
.chunk(100, transactionManager) // 100개씩 처리
왜 청크 크기가 줄어들었을까요?
- 1단계에서 이미 집계된 데이터라 양이 적음
- 더 안정적인 처리를 위해 작은 청크 선택
- 스킵 허용량도 1개로 줄임 (데이터 품질이 더 중요)
3단계: 조건부 실행 분기점 (FirstDayOfMonthDecider)
.next(firstDayOfMonthDecider)
.on(FIRST_DAY).to(productOrderStatMonthlyStep)
.on(NOT_FIRST_DAY).end()
핵심 설계 철학:
- 매일 실행되지만 필요한 작업만 수행
- 월별 통계는 매월 1일에만 생성
- 시스템 리소스 효율적 활용
4-5단계: 월별 통계 생성 (월 첫날만)
월별 통계 생성 단계들은 일일 통계와 비슷하지만:
- 더 작은 청크 크기 (100개)
- 더 엄격한 오류 처리 (스킵 1개)
- 월 단위 집계 로직 적용
🛡️ 안정성 및 성능 최적화
오류 처리 전략
재시도 정책 (Retry Policy)
.retry(Exception.class)
.retryLimit(3)
.backOffPolicy(exponentialBackOffPolicy())
실무에서는 다양한 오류가 발생합니다:
- 데이터베이스 일시적 연결 오류
- 네트워크 타임아웃
- 메모리 부족 등
지수 백오프를 사용하는 이유:
- 시스템이 복구될 시간을 제공
- 연속적인 재시도로 인한 시스템 부하 방지
- 1초 → 2초 → 4초 (최대 30초)
스킵 정책 (Skip Policy)
.skip(Exception.class)
.skipLimit(5) // 1단계
.skipLimit(1) // 2-5단계
왜 단계별로 스킵 허용량이 다를까요?
- 1단계: 원시 데이터라 품질 문제 가능성 높음
- 2-5단계: 이미 검증된 데이터라 엄격한 기준 적용
성능 최적화
청크 크기 최적화:
- 대용량 원시 데이터: 1,000개 (처리 속도 우선)
- 집계 데이터: 100개 (안정성 우선)
트랜잭션 관리:
- 청크 단위별 개별 트랜잭션
- 부분 실패 시에도 전체 작업 영향 최소화
🎯 실무 적용 팁
모니터링 포인트
- 실행 시간 모니터링
- 일일 통계: 보통 30분 이내
- 월별 통계: 2-3시간 소요 가능
- 오류율 추적
- 스킵된 데이터 건수 확인
- 재시도 발생 패턴 분석
- 데이터 품질 검증
- 통계 결과 일관성 체크
- 전일 대비 급격한 변화 감지
운영 시 주의사항
월 첫날 리소스 관리:
// 월 첫날에는 더 많은 메모리와 CPU 사용
// 인프라 스케일링 고려 필요
장애 대응 시나리오:
- 1-2단계 실패: 해당 일자 재실행
- 3-4단계 실패: 월별 통계만 별도 실행
- 부분 실패: 스킵된 데이터 별도 처리
확장성 고려사항
수평 확장:
- Reader를 파티셔닝하여 병렬 처리
- 상품 카테고리별 분산 처리 가능
수직 확장:
- 청크 크기 조정으로 메모리 사용량 최적화
- 처리 성능과 안정성 균형점 찾기
🔍 질의응답 예상 질문
Q1: 왜 월별 통계를 매월 1일에만 생성하나요? A: 월별 통계는 해당 월의 모든 일일 데이터가 필요합니다. 매월 1일에 전월 데이터를 기반으로 생성하는 것이 효율적이죠.
Q2: 배치 실행 중 장애가 발생하면 어떻게 되나요? A: Spring Batch의 JobRepository가 실행 상태를 추적합니다. 중단된 지점부터 재시작 가능하며, 청크 단위로 트랜잭션이 관리되어 부분 실패에도 안전합니다.
Q3: 성능 개선 방법은? A: 청크 크기 조정, 병렬 처리, 인덱스 최적화, 파티셔닝 등 다양한 방법이 있습니다. 데이터 특성에 맞는 최적화가 핵심입니다.
📝 마무리
오늘 소개한 배치 시스템의 핵심은:
- 조건부 실행으로 리소스 효율성 확보
- 단계별 최적화된 청크 크기와 오류 처리
- 안정성과 성능의 균형
- 실무 적용 가능한 설계 패턴