Spring Batch chunk-oriented Step

들어가며

Step은 Job에서 독립적으로 실행되는 도메인 객체입니다. 하나의 Job에 N개의 Step이 올수 있습니다.
이전까진 Step의 tasklet을 이용해 간단한 예제를 살펴보았는데요, 이번 포스팅에선 chunk-oriented Step에 대해 알아보도록 하겠습니다.

 


Chunk-Oriented

Step은 tasklet/chunk 두가지 작업 방식을 지원합니다.
두 방식은 컨셉 차이가 있기 때문에 용도의 맞춰 프로그래밍을 하는게 좋습니다.
아래에서 tasklet, chunk 방식에 대해 간략히 알아보도록 하겠습니다.

  • tasklet
    • 단일 작업에 사용합니다
    • 일반적으로 Resource 삭제하거나 단순 쿼리를 질의하는 등 단일 작업을 수행합니다
  • chunk
    • 복잡한 작업세 사용합니다
    • Reader, Processor, Writer 3가지 단계로 구성됩니다
    • Reader, Writer는 필수이며 Processor는 선택적으로 사용됩니다
    • 즉, 데이터 읽기, 가공, 저장의 순으로 처리됩니다

간단히 두 방식의 차이점을 알아보았습니다.
tasklet은 복잡하지 않은 단일 작업에, chunk는 복잡하고 데이터를 읽어서 가공 처리해야 할 경우 사용하는 것이 적합합니다.
우리가 구현하고자 하는 대부분의 batch 작업은 복잡하고 거대하기 때문에 일반적으로 chunk-oriented 방식을 많이 사용합니다.


Chunk란?

Chunk란 데이터 작업의 묶음으로, Items를 묶어 처리되는 row수를 얘기합니다.
즉, Chunk 지향 프로세싱이란 한번에 하나씩 데이터를 읽어 Chunk 묶음을 만들고 Chunk 단위로 트랜젹선을 다루는 것을 말합니다.
Chunk 단위로 트랜잭션을 수행하기 때문에 실패할 경우엔 해당 Chunk만큼 롤백이 되고, 이전에 커밋된 트랜잭션 범위까지 반영이 된다는 것입니다.


Chunk-processing

그림으로, Chunk 지향 프로세싱의 처리를 알아보도록 하겠습니다.
Page Size 5000, Chunk Size 5000이라고 가정

  • page-size: Resource에서 읽어올 데이터 묶음 단위
  • chunk-size: 읽어온 데이터를 처리할 데이터 묶음 단위
    Page size = chunk size *n으로 구성하는 것이 좋고, 일반적으로는 page와 chunk 사이즈를 동일하게 구성합니다.
  1. 먼저, page 수 만큼 db 질의를 하여 데이터를 읽어옵니다
  2. Reader는 5000개를 질의하여 List를 가져오고, 한건씩 Processor에게 전달하여 줍니다
  3. 프로세서는 한건씩 데이터를 가공하고 5000건이 모이면 Writer에게 처리하여 줍니다.
  4. Writer를 청크사이즈만큼 일괄처리합니다.
  5. 1~4번 다시 수행
  6. data가 Null이 나올때까지 반복하여 줍니다.

Chunk-processing example

DB로부터 data를 조회할시에는 Reader로 DatabaseReader를 사용하게 됩니다. PagingItemReader, CursorItemReader 두 종류가 있습니다. 이 부분은 추후 포스팅으로 다시 정리하도록 하겠습니다

이번 포스팅에서는 baeldung 블로그에서 chunk 지향 Step에 대한 예를 가져왔습니다.
간략히 chunk 기반 시스템이 어떻게 구성되고 동작하는지만 알아보도록 하겠습니다.

@Configuration
@EnableBatchProcessing
public class ChunksConfig {

    @Autowired 
    private JobBuilderFactory jobs;

    @Autowired 
    private StepBuilderFactory steps;

    @Bean
    public ItemReader<Line> itemReader() {
        return new LineReader();
    }

    @Bean
    public ItemProcessor<Line, Line> itemProcessor() {
        return new LineProcessor();
    }

    @Bean
    public ItemWriter<Line> itemWriter() {
        return new LinesWriter();
    }

    @Bean
    protected Step processLines(ItemReader<Line> reader,
      ItemProcessor<Line, Line> processor, ItemWriter<Line> writer) {
        return steps.get("processLines").<Line, Line> chunk(2)
          .reader(reader)
          .processor(processor)
          .writer(writer)
          .build();
    }

    @Bean
    public Job job() {
        return jobs
          .get("chunksJob")
          .start(processLines(itemReader(), itemProcessor(), itemWriter()))
          .build();
    }
}
  • Job “chunksJob”이 실행됩니다
  • Job 내부에 start를 보면 독립적인 도메인은 Step을 호출합니다
  • Step “processLines“이 실행됩니다
  • processLines은 chunk 지향 Step으로 itemReader, itemProcessor, itemWriter로 구성되어 단계별로 실행됩니다.

참조

jojoldu님 블로그 - 6. Spring Batch 가이드 - Chunk 지향 처리
baeldung 블로그 tasklet vs chunk - Spring Batch - Tasklets vs Chunks | Baeldung
spring.batch.io - Configuring a Step

블로그 이미지

사용자 yhmane

댓글을 달아 주세요