[Spring] Spring Batch를 사용해보면서
프로젝트에서 배치를 사용하게되면서 Spring batch를 적용해보면서 느낀점에 대해 정리한 글입니다.
매일 한국 시간 기준 오전 11시와 오후 1시에 서비스를 실행되어야 한다면
MVC 패턴에서 적용시 Controller 단에서 @Scheduled cron 식으로 스케줄링하여 처리할 수 있다.
@Scheduled(cron = "0 0 11,17 * * *",zone = "Asia/Seoul")
대용량 데이터를 처리 해야 할 때
주로 이런 서비스는 대용량 데이터를 일괄적으로 처리하는 서비스 일 것이다.
만약 이와 같은 서비스에서 1000만 건의 데이터를 처리 해야 한다면 말이 달라집니다.
1000만건의 데이터를 데이터 블록에 적재해놓고 하나씩 처리한다면 메모리적으로 좋은 방법이 아닙니다.
"페이지네이션을 사용하면 메모리를 최적화할 수 있지 않나?" 맞습니다. 메모리 적으로 더 나은 방법입니다.
하지만 RDBS 특성상 페이지가 증가할수록 성능이 저하됩니다.
커버링 인덱싱, fetch-first-clause 방식으로 pagenation을 최적화할 수 있습니다.
만약 Task가 실패한다면, ErrorHandling은 어떻게 할 것인가
이러한 문제에 직면해 있다면 Spring Batch 채택을 고려해도 좋습니다.
Spring Batch에서 Chunk 활용
Spring batch에서는 Chunk를 사용할 수 있는데
Batch에서는 Reader - Processor - Writer (이하 RPW) 방식으로 Job을 처리하는데
Chunk란 100개의 데이터를 ChunkSize 3으로 Job을 실행하면 총 34번 반복하면서 3개씩 RPW를 실행한다.
1000만 건의 데이터를 RPW 할 경우 1000만 건을 한 번에 메모리에 올려놓으면 메모리 릭이 발생할 확률이 높아진다.
따라서 Chunk를 사용하는 것이다.
Chunk는 Job의 Step에서 설정해줄 수 있는데 Step에서 예기치 못한 error가 발생했을 때 즉시 종료하는 것이 아닌
FaultTolerant 구조에서 retry, skip 같은 옵션도 제공해 준다.
public Step chunkStep() {
return stepBuilderFactory.get(CHUNK_NAME)
.<PushTable, BatchStatistic>chunk(3)
.reader(this.itemReader())
.processor(this.itemProcessor())
.writer(this.itemWriter())
.faultTolerant()
.skip(SkipException.class)
.skipLimit(100)
.build();