사부작사부작
스프링 배치 3주차 본문
이번 주차의 스터디 주제는 Chunk Model 과 TaskletModel 입니다 .
먼저 들어가기 앞서 단어 뜻을 찾아보겠습니다.


chunk 는 ‘덩어리’ 라는 뜻을 나타냅니다. tasklet 에는 한글 뜻이 없어서 번역해보면 ‘운영체제에서의 간단한 작업’ 라고 해석할 수 있습니다.
그리고 스터디의 주제인 batch 는 아래의 뜻을 가지고 있습니다.

배치는 ‘일괄적으로 묶은 한 회분’ 의 뜻을 가지고 있습니다.
Chunk의 뜻을 더 찾아보니 여기서 말하는 ‘덩어리’는 특정 큰 단위에서 나온 덩어리를 의미합니다. 단어 뜻 대로 청크모델은 배치 작업을 한 번에 모두 처리하지 않고 일정한 크기(청크)로 나누어 처리하는 방식입니다. 이에 반해 taskletModel은 단일 작업 단위로 배치를 수행하는 방밥입니다.
단어 뜻에서도 느껴지듯이 스프링은 대규모 데이터를 다루기위한 ChunkModel과 간단한 배치작업을 위한 TaskletModel을 제공하고 있습니다. 이를 더 살펴 보겠습니다.
Chunk
Spring Batch의 Step은 Chunk, Tasklet 2가지 나눠지고 Chunk인 경우, ItemReader -> ItemProcessor -> ItemWriter로 프로세스가 진행됩니다. 개별 데이터 row 단위로 읽고 가공한 뒤, row를 덩어리로 모아서 쓰는 과정으로 진행됩니다. 해당 과정은 아래 그림과 같습니다.

이 과정에 대한 예시 수도 코드입니다.
List items = new Arraylist();
for(int i = 0; i < commitInterval; i++){
Object item = itemReader.read();
if (item != null) {
items.add(item);
}
}
List processedItems = new Arraylist();
for(Object item: items){
Object processedItem = itemProcessor.process(item);
if (processedItem != null) {
processedItems.add(processedItem);
}
}
itemWriter.write(processedItems);
이 과정에서 사용되는 ItemReader, ItemProcessor, ItemWriter 구현체들은 특정한 용도와 상황에 맞게 설계되었습니다.
예를 들면 ItemReader 의 경우 다양한 읽기 소스에 대한 구현체가 존재합니다. CSV, 텍스트 파일의 읽기용 구현체(FlatFileItemReader), Jpa페이징 방식 읽기용 구현체(JpaPagingItemReader) 등의 여러 구현체를 제공해줍니다. ItemProcessor의 경우엔 입력된 데이터를 확인하는 구현체(ValidatingItemProcessor), 여러 개의 프로세서를 조합해서 사용하는 구현체(CompositeItemProcessor) 등을 제공해줍니다. 또한 ItemWritrer 의 경우에도 CSV, 텍스트 파일의 데이터를 쓰는 구현체(FlatFileItemWriter), JPA를 사용해서 데이터를 쓰는 구현체(JpaItemWriter) 등이 존재합니다.
Chunk 모델은 데이터를 나눠서 처리함으로써 여러 이점을 가져갑니다.
- 트랜잭션 관리 및 재시도 용이
배치로 처리할 데이터가 아주 많은 상황을 생각해봅겠습다. 스프링 배치는 배치 작업 과정에서 트랜잭션을 관리해줍니다. 배치 처리 중에 오류가 발생해 작업이 진행된 수많은 데이터의 롤백이 발생할 수 있습니다. 이 때 데이터를 특정 단위로 나눠서 반복 처리를 한다면 안정적인 작업과 효율성을 보다 보장할 수 있습니다.
- 성능 최적화
청크 단위로 데이터를 읽고, 처리하고, 쓰는 과정을 병렬로 수행할 수 있습니다.
처리할 데이터의 규모 뿐만 아니라 처리할 상황도 어떤 배치 모델을 선택할지 고려사항 중 하나입니다. 만약 외부 api 호출이나 db 업데이트 sql 처리가 필요한 상황을 생각해봅시다. 이 때 reader, processor, writer 로 구성된 청크 모델을 사용한다면 writer는 작동하지 않게 됩니다. 그렇기에 간단한 작업이 필요한 경우에도 tasklet을 사용합니다.
Tasklet
package org.springframework.batch.core.step.tasklet;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.repeat.RepeatStatus;
/**
* Callback interface to be implemented by classes that perform single tasks within a Step.
*/
public interface Tasklet {
/**
* Execute the task.
*
* @param contribution the current step execution context
* @param chunkContext the current chunk context
* @return the status indicating whether processing is finished or should continue
* @throws Exception in case of any error that should stop the step
*/
RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
}
execute 메서드는 Tasklet의 핵심 메서드로, 실제 작업 로직이 구현됩니다. 반환타입의 enum은 2가지 상태를 표시해줍니다.
package org.springframework.batch.repeat;
public enum RepeatStatus {
FINISHED,
CONTINUABLE
}
작업이 완료되었음을 나타내는 FINISHED를 반환하거나, 추가적인 처리가 필요할 경우 CONTINUABLE을 반환하게 됩니다. 이때 반환값으로 CONTINUABLE을 반환하면 태스크는 재실행되어 반환값이 FINISHED가 나올때까지 반복하게 됩니다. 그렇기에 무한루프에 빠지지 않기 위해선 적절한 처리가 필요합니다.
Tasklet도 Chunk방식처럼 다양한 구현체를 제공하고 있습니다. 시스템 명령어를 실행하는 구현체(SystemCommandTasklet), 지정된 파일을 삭제하는 구현체( FileDeletingTasklet) 등이 존재합니다.
'스터디' 카테고리의 다른 글
| Custom ItemReader/ItemWriter 구현방법 알아보기 (1) | 2024.12.09 |
|---|---|
| JpaPagingItemReader, JpaItemWriter (2) | 2024.11.12 |
| JdbcPagingItemReader와 JdbcBatchItemWriter (1) | 2024.11.05 |
| 스프링 배치 스터디 2주차 (0) | 2024.10.14 |