본문 바로가기

프로그램/java

[Spring] Spring Batch ( With Chunk & Tasklet )

[출처] [Spring] Spring Batch ( With Chunk & Tasklet )|작성자 양기열

 

-스프링 배치란

: 일괄 처리 기능 구현에 사용됨 (스케줄러 기능은 쿼츠나 젠킨스를 사용하여 별도의 연동이 필요하다.)

ex) 1년이상 휴먼회원의 상태를 변경하는 작업.(일일배치)

-주요애노테이션

@EnableBatchProcessing : 배치기능 활성화 - 메인 메소드가 있는 배치 클래스에 작성.

@Configuration : 스프링배치의 모든 잡은 @configulation으로 등록해서 사용함.

@Slf4j // log 사용을 위한 lombok 어노테이션
@RequiredArgsConstructor // 생성자 DI를 위한 lombok 어노테이션
@Configuration
public class SimpleJobConfiguration {
    private final JobBuilderFactory jobBuilderFactory; // 생성자 DI 받음
    private final StepBuilderFactory stepBuilderFactory; // 생성자 DI 받음

    @Bean
    public Job simpleJob() {
        return jobBuilderFactory.get("simpleJob")
                .start(simpleStep1())
                .build();
    }

    @Bean
    public Step simpleStep1() {
        return stepBuilderFactory.get("simpleStep1")
                .tasklet((contribution, chunkContext) -> {
                    log.info(">>>>> This is Step1");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }
}

-주요객체

jobBuilderFactory.get("simpleJob") : simpleJob 이란 이름의 배치 잡을 생성.

stepBuilderFactory.get("simpleStep1") : simpleStep1 이란 이름의 배치 스탭을 생성.

-주요메서드

next() : 순차적으로 Step들을 연결시킬때 사용됨( step1 -> step2 -> step3 ... )

flow : 조건별 Step연결 ( step1 성공시 stepB, 실패시 StepC 가 실행되도록 실행 흐름 제어 가능 )

-Flow
*.on()
캐치할 ExitStatus 지정 * 일 경우 모든 ExitStatus가 지정된다.
 
*to()
다음으로 이동할 Step 지정
 
*from() 일종의 이벤트 리스너 역할 상태값을 보고 일치하는 상태라면
to()에 포함된 step을 호출합니다. step1의 이벤트 캐치가
FAILED로 되있는 상태에서 추가로 이벤트 캐치하려면 from을 써야만 함
 
*end()
end는 FlowBuilder를 반환하는 end와 FlowBuilder를 종료하는 end 2개가 있음
on("*")
뒤에 있는 end는 FlowBuilder를 반환하는 end
build()
앞에 있는 end는 FlowBuilder를 종료하는 end FlowBuilder를 반환하는 end 사용시 계속해서 from을 이어갈 수 있음

 

 

decider() -> Flow는 Step이 담당하는 역할이 2개이상이 되고, 다양한 분기 로직 처리가 어려움.

SO Decide는 분기만 담당하는 타입으로 구현 가능.

-Job

: 하나의 배치 작업 단위

-Step

Tasklet OR (Reader,Processor,Writer) 묶음이 존재

-Chunk

: 덩어리, 각 커밋 사이에 처리되는 row수.

한번에 하나씩 데이터를 읽어 Chunk라는 덩어리를 만든 뒤, Chunk단위로 트랜잭션을

Chunk단위로 커밋 or 롤백이 발생.

read() -> process() -> write()

-Tasklet

: Step 안에서 단일로 수행될 커스텀한 기능들을 선언할때 사용.

각 단계는 하나의 정의 된 작업만 수행해야 함.

execute() 메소드를 구현해야함.

- Page Size, Chunk Size

Page Size : 한번에 조회할 Item의 양.

Chunk Size : 한번에 처리될 트랜잭션 단위.

ex)PageSize가 10이고, ChunkSize가 50이라면 ItemReader에서 Page 조회가 5번 일어나면 1번 의 트랜잭션이 발생하여 Chunk가 처리됩니다. 한번의 트랜잭션 처리를 위해 5번의 쿼리 조회가 발생하기 때문에 성능상 이슈가 발생할 수 있습니다. 그래서 Spring Batch의 PagingItemReader에는 클래스 상단에 다음과 같은 주석을 남겨두었습니다. Setting a fairly large page size and using a commit interval that matches the page size should provide better performance. (상당히 큰 페이지 크기를 설정하고 페이지 크기와 일치하는 커미트 간격을 사용하면 성능이 향상됩니다.) + 성능상 이슈 외에도 2개 값을 다르게 할 경우 JPA를 사용하신다면 영속성 컨텍스트가 깨지는 문제도 발생합니다.

-> 2개 값이 의미하는 바가 다르지만 위에서 언급한 여러 이슈로 2개 값을 일치시키는 것이 보편적으로 좋은 방법이니 꼭 2개 값을 일치시키시길 추천드립니다. ( Page Size = Chunk Size )

-메타 테이블

BATCH_JOB_INSTANCE : Job Parameter에 따라 생성되는 테이블

BATCH_JOB_EXECUTION : 자신의 부모 JOB_INSTACNE가 성공/실패했던 모든 내역을 갖고 있습니다.

-Reference

https://jojoldu.tistory.com/324