본문 바로가기
Spring

[Spring] Spring Batch - 잡과 스텝 이해하기

by soro.k 2021. 11. 10.

'스프링 배치 완벽 가이드'의 내용을 바탕으로 작성된 개인 공부를 위한 기록용 포스트입니다.


잡의 생명주기
  • 잡의 실행은 Job runner에서 시작된다. 잡 러너는 잡 이름과 여러 파라미터를 받아들여 잡을 실행시키는 역할을 한다.
  • JobExecution잡 실행의 실제 시도를 의미한다. 잡이 처음부터 끝까지 단번에 실행 완료됐다면 해당 JobInstance와 JobExecution은 단 하나씩만 존재한다.
  • 첫 번째 잡 실행 후 오류 상태로 종료됐다면, 해당 JobInstance실행하려고 시도할 때마다 새로운 JobExecution이 생성된다.
스텝 알아보기

스텝은 독립적이고 순차적으로 배치 처리를 수행한다. 모든 단위 작업의 조각으로 자체적으로 입력을 처리하고 자체적인 처리기를 가질 수 있으며 자체적으로 출력을 처리한다. 트랜잭션은 스텝 내에서 이루어지며 스텝은 서로 독립되도록 의도적으로 설계됐다.

  • Tasklet 모델
    • Tasklet.execute 메서드가 RepeatStatus.FINISHED를 반환할 때까지 트랜잭션 범위 내에서 반복적으로 실행되는 코드 블록을 만들 수 있음
  • Chunk 기반 처리 모델
    • 2~3개의 주요 컴포넌트로 구성되며 이러한 컴포넌트를 사용해 레코드를 청크 또는 레코드 그룹 단위로 처리
    • 각 청크는 자체 트랜잭션으로 실행되며, 처리에 실패했다면 마지막으로 성공한 트랜잭션 이후부터 다시 시작할 수 있음
      • IteamReader : 청크 단위로 처리할 모든 레코드들을 반복적으로 메모리로 읽어옴
      • ItemProcessor : 메모리로 읽어들인 아이템은 반복적으로 ItemProcessor를 거쳐감.
      • ItemWriter : 모든 아이템을 전달, ItemWriter의 단일 호출은 물리적 쓰기를 일괄적으로 처리함으로써 IO 최적화를 이룬다.
스텝 구성

스프링 배치는 기본적으로 각 스텝이 상태와 다음 상태로 이어지는 전이의 모음을 나타내는 상태 머신이다.

  1. Tasklet 스텝
  2. Chunk 스텝

커밋 간격에 의해 정의된다. 커밋 간격을 50개 아이템으로 설정했다면 잡은 50개 아이템을 읽고 50개 아이템을 처리한 다음에, 한번에 50개 아이템을 기록한다. 단순히 쓰기 측면에서 최상의 성능을 얻으려면 커밋 간격을 어느 정도 크게 설정하는 것이 중요하다.

 

[스텝 리스너]

각각 스텝과 청크의 시작과 끝에서 특정 로직을 처리할 수 있게 해준다.

 

[스텝 플로우]

  • 조건 로직
    • 스프링 배치의 스텝은 잡 내에서 StepBuilder의 next의 메서드를 이용해 지정한 순서대로 실행된다. 빌더를 사용해 잡의 진행 방향을 지정할 수 있다.

<on 메서드>

  • *는 0개 이상의 문자를 일치시킨다는 것을 의미한다. 예를 들어 C**는 C, COMPLETE, CORRECT와 일치한다.
  • ?는 1개의 문자를 일치시킨다는 것을 의미한다. 예를 들어 ?AT는 CAT, KAT과 일치하지만 THAT과는 일치하지 않는다.
  • BatchStatus = 잡이나 스텝의 현재 상태를 식별하는 JobExecution이나 StepExecution의 애트리뷰트다.
  • ExitStatus = 잡이나 스텝 종료 시 스프링 배치로 반환되는 값
  • FlowExecutionStatus = BatchStatus/ExitStatus 쌍을 래핑한 래퍼 객체

<잡 종료 하기>

잡을 종료할 때 세 가지 상태로 종료 가능

  • Completed : 스프링 배치 처리가 성공적으로 완료
  • Failed : Failed 상태로 종료된 잡은 스프링 배치를 사용해 동일한 파라미터로 다시 실행 가능
  • Stopped : 잡에 오류가 발생하지 않았지만 중단된 위치에서 잡을 다시 시작할 수 있음. 이 상태는 스텝 사이에 사람의 개입이 필요하거나 다른 검사나 처리가 필요한 상황에 매우 유용.

<플로우 외부화하기>

스텝의 순서를 외부화하는 세 가지 방법

  • 스텝의 시퀀스를 독자적인 플로우로 만드는 방법
  • 플로우를 잡 빌더로 전달해 플로우를 실행하도록 구성
  • 플로우 스텝을 사용하는 방법
    • 해당 플로우를 스텝으로 래핑하고 이 스텝을 잡 빌더로 전달
    • 플로우를 잡 빌더로 전달 vs 플로우 스텝을 사용
      • 플로우 스텝을 사용하면 개별 스텝을 집계하지 않고도 플로우의 영향을 전체적으로 볼 수 있다.
  • 잡 내에서 다른 잡을 호출하는 방법