Study/Spring

Spring Batch에서 병렬 처리하기

going.yoon 2022. 6. 20. 15:16

다중 스레드 스텝

스프링 배치에서 step은 기본적으로 단일 스레드로 처리된다. 다중 스레드 스텝은 잡의 실행을 병렬화하기 가장 쉬운 방법이다. 잡 안의 step 내에서 청크 단위로 다중 스레드 작업을 하는 방식이다.

 

스프링 배치의 다중 스레드 스텝 개념을 적용하면, 스탭 내의 각각의 청크들이 자체 스레드에서 실행되게 할 수 있다.

org.springframework.core.task.TaskExecutor 추상화를 사용하면 된다.

 

 

각 청크를 독립적으로 처리하면서 하나의 스레드 풀 내에서 처리되게 구성하고, 청크가 처리될 때 에러가 발생하면 롤백되거나 종료된다.

 

@Bean
public Step step1(){
	return this.stepBuilderFactory().get("step1")
    	.<Transaction, Transaction>chunk(100)
        .reader(fileTransactionReader(null))
        .writer(writer(null))
        .taskExecutor(new SimpleAsyncTaskExecutor()) // 이런식으로 step 정의
        .build();
}

 

하지만 이러한 다중 스레드 스텝을 사용할 때 주의 사항은 Reader가 Thread-safe한지 파악해야하고 , Reader 부분에서 부하가 많다면 다중스레드 스텝을 사용해도 별로 성능 개선에 효과가 없다.

 

 

병렬 스텝

다중 스레드 스텝과 달리 병렬 스텝은 스텝 자체를 병렬처리 하는 것이다. 이를 위해서 TaskExecutor를 다시 사용한다. 각 플로우는 자체 스레드에서 실행되므로 여러 플로우를 병렬로 실행할 수 있다. FlowBuilder의 split메소드를 사용하면 TaskExecutor를 아규먼트로 받아서 SplitBuilder를 반환한다. 이를 사용해서 원하는 만큼 많은 플로우 객체를 추가할 수 있다.

 

split 메서드를 사용했을 때 잡의 실행 순서도 일반적인 잡의 실행 순서와 유사하다. 일반적인 잡에서는 스탭 내에서 처리해야할 모든 아이템이 처리되기 전에는 해당 스텝이 완료되지 않으면 해당 스텝이 완료되지 않으며, 해당 스텝이 완료되지 않았다면 다음 스텝이 시작되지 않는다. split 메서드를 사용했다면 split 메소드를 통해 병렬로 수행되도록 구성된 모든 플로우가 완료될 때 까지 이후 스텝은 실행되지 않는다.

 

@Bean
public Job parrallelStepJob() {
	Flow secondFlow = new FlowBuilder<Flow>("secondFlow")
    				 .start(step2())
                     .build();
                     
    Flow parallelFlow = new FlowBuilder<Flow>("parallelFlow")
    					.start(step1())
                        .split(new SimpleAsyncTaskExecutor()) // taskExecutor 호출
                        .add(secondFlow) // 플로우 객체 추가
                        .build();
                        
    return this.jobBuilderFactory.get("parallelStepsJob")
    			.start(parallelFlow)
                .end()
                .build();
}