대규모 시스템에서는 한 번에 수십만~수백만 건의 데이터를 처리해야 하는 상황이 자주 발생합니다. 예를 들어 일일 정산, 로그 집계, 통계 업데이트 같은 작업이 그렇습니다. 이런 배치성 작업을 단순한 루프로 구현하면 메모리 과부하나 트랜잭션 실패로 이어질 수 있습니다. 이럴 때 사용하는 대표적인 프레임워크가 바로 Spring Batch입니다.
Spring Batch란?
Spring Batch는 대량의 데이터를 안정적으로 처리하기 위한 배치 처리 프레임워크입니다. 단순 반복 작업이 아니라, Chunk 기반 처리, 트랜잭션 제어, 재시도 및 실패 복구 기능을 포함하고 있습니다.
Spring Batch는 다음과 같은 특징을 가집니다:
- 대량 데이터 처리: 수십만 건 이상의 데이터도 안정적으로 처리
- 트랜잭션 단위 제어: Chunk 단위로 커밋/롤백 관리
- 재시도/스킵 기능: 에러 발생 시 특정 레코드만 건너뛰거나 재시도 가능
- 다양한 Reader/Writer 지원: JDBC, JPA, FlatFile, XML, JSON 등
Spring Batch 기본 구조
Spring Batch의 구조는 Job → Step → Chunk의 계층으로 구성됩니다.
- Job: 하나의 배치 작업 단위를 의미 (예: "회원 포인트 정산 Job")
- Step: Job을 구성하는 세부 단계 (예: "데이터 조회 → 처리 → 저장")
- Chunk: 일정 단위로 데이터를 나누어 커밋 (예: 1000건 단위 처리)
즉, 전체 데이터를 한 번에 처리하지 않고, Chunk 단위로 잘라서 트랜잭션을 안정적으로 관리합니다.
Spring Batch 설정 예시
1. 의존성 추가 (Gradle)
implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.mysql:mysql-connector-j'
2. Job & Step 구성 예시
@Configuration
@RequiredArgsConstructor
public class SampleBatchConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final DataSource dataSource;
@Bean
public Job sampleJob() {
return jobBuilderFactory.get("sampleJob")
.start(sampleStep())
.build();
}
@Bean
public Step sampleStep() {
return stepBuilderFactory.get("sampleStep")
.<String, String>chunk(1000)
.reader(sampleReader())
.processor(sampleProcessor())
.writer(sampleWriter())
.build();
}
@Bean
public ItemReader<String> sampleReader() {
return new ListItemReader<>(List.of("A", "B", "C"));
}
@Bean
public ItemProcessor<String, String> sampleProcessor() {
return item -> item + " processed";
}
@Bean
public ItemWriter<String> sampleWriter() {
return items -> items.forEach(System.out::println);
}
}
위 코드는 단순한 예시이지만, 실제로는 Reader에서 DB나 파일을 읽고, Processor에서 데이터 가공, Writer에서 결과를 저장하는 형태로 동작합니다.
실행 방식
Spring Boot 애플리케이션 실행 시, 기본적으로 spring.batch.job.enabled=true 설정이 되어 있으면 정의된 Job이 자동으로 실행됩니다. 여러 Job을 관리하려면 JobLauncher를 이용해 수동 실행도 가능합니다.
@RestController
@RequiredArgsConstructor
public class BatchController {
private final JobLauncher jobLauncher;
private final Job sampleJob;
@GetMapping("/run-batch")
public String runBatch() throws Exception {
JobParameters params = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(sampleJob, params);
return "Batch started!";
}
}
위처럼 간단한 REST API를 통해 배치를 실행하면, 외부 트리거(Cron, Jenkins, Scheduler 등)와 연동하기도 쉽습니다.
대량 데이터 처리 시 주의할 점
- Chunk 크기 조정: 너무 크면 메모리 부담, 너무 작으면 성능 저하
- Reader/Writer 최적화: JDBC Batch 기능 사용, JPA flush 주기 조정
- 트랜잭션 범위 확인: Chunk 단위로 커밋되므로 데이터 정합성 고려 필요
- 장애 복구: Spring Batch는 JobRepository에 실행 이력을 저장하므로, 실패한 Step부터 재시작 가능
실무 활용 예시
- 매일 새벽 3시: 전일 매출 데이터 집계
- 매시간: 외부 API 데이터를 수집 후 DB 적재
- 매일: 로그 파일 압축 및 백업
- 주기적 정산 및 리포트 생성
이러한 작업을 Spring Batch로 구성하면 에러 복구, 중단 재개, 병렬 처리가 가능해 안정성과 확장성이 높습니다.
Spring Batch vs Scheduler
Spring Batch와 @Scheduled는 자주 혼동되지만, 목적이 다릅니다:
- Scheduler: 주기적인 실행(“언제”)에 집중
- Batch: 대량 데이터 처리(“무엇을 어떻게”)에 집중
따라서, Scheduler → Batch Job 실행 형태로 함께 사용하는 것이 일반적입니다.
Job 실행 결과 확인
Spring Batch는 실행 정보를 JobRepository에 자동 저장합니다. 기본적으로 H2, MySQL 등 관계형 DB를 사용하며, 아래 테이블들이 생성됩니다:
BATCH_JOB_INSTANCE— Job 단위 실행 정보BATCH_JOB_EXECUTION— 실행 상태(시작, 종료, 실패 등)BATCH_STEP_EXECUTION— Step별 상세 이력
이 정보들을 기반으로 성공률, 처리 건수, 평균 처리 시간을 모니터링할 수 있습니다.
주의할 점
- 대량 데이터 처리 시 메모리 사용량 주의
- 트랜잭션 경계(Chunk 크기) 설정 신중히
- Reader/Writer 간 동기화 문제 방지
- Job이 중복 실행되지 않도록 JobParameters를 고유하게 설정
Spring Batch는 단순히 데이터를 “반복 처리”하는 수준을 넘어, 트랜잭션 관리·장애 복구·대용량 처리 성능까지 고려된 프레임워크입니다. 특히 정산, 통계, 로그 수집 등 정기적 대량 처리 작업이 필요한 서비스라면 Spring Batch 도입을 적극 추천합니다. 다음 글에서는 Spring Batch의 Chunk 기반 처리 흐름과 병렬 Step 실행을 더 깊이 있게 다루겠습니다.
'개발 > JAVA' 카테고리의 다른 글
| [JAVA] Spring Cloud 소개 — 마이크로서비스 아키텍처의 핵심 구성 이해 (0) | 2025.11.03 |
|---|---|
| [JAVA] Spring Batch와 JPA 연동하기 — 대량 데이터 처리에서의 효율적인 영속성 관리 (0) | 2025.11.02 |
| [JAVA] Spring Scheduler와 @Scheduled 사용법 — 안정적인 스케줄링 구현하기 (0) | 2025.10.31 |
| [JAVA] 로깅과 AOP를 이용한 공통 로직 처리 (0) | 2025.10.30 |
| [JAVA] Spring AOP에서 @Aspect와 @Around 어노테이션 제대로 활용하기 (0) | 2025.10.29 |
