Study/스프링배치 완벽 가이드

Day 2. 스프링 배치

주지민 2021. 11. 5. 00:52
반응형
스프링 배치 완벽 가이드 내용 정리입니다

 

http://www.yes24.com/Product/Goods/99422216

 

스프링 배치 완벽 가이드 2/e - YES24

스프링 배치의 `Hello, World!`부터 최근 플랫폼의 발전에 따른 클라우드 네이티브 기술을 활용한 배치까지 폭넓은 스프링 배치 활용 방법과 이와 관련된 유용한 내용을 다룬다. 또한 스프링 프레임

www.yes24.com


1. 스프링 배치

  • 스프링 배치 구성
    • 어플리케이션 레이어: 개발자가 개발하는 코드 영역, 대부분 코어 레이어와 상호작용
    • 코어 레이어: 배치 영역을 구성하는 실제적인 여러 컴포넌트로 이루어져 있다
    • 인프라스터럭처 레이어: ItemReader, ItemWriter를 비롯해, 재시작과 관련된 문제를 해결할 수 있는 클래스, 인터페이스를 제공한다

 

2. Job과 Step

  • 자바나 XML을 사용해 구성된 배치 잡은 상태를 수집하고 이전 상태에서 다음 상태로 전환된다
  • 스텝은 잡을 구성하는 독립된 작업의 단위이다
  • 스텝 구성 요소
    • Tasklet기반 스텝
      • 간단한 구조
      • Tasklet을 구현하면 된다
      • 스텝이 중지될 때까지 execute 메서드가 계속 반복해서 수행된다 ( execute 메서드를 호출할 때마다 독립적인 트랜잭션이 얻어짐 )
      • 초기화, 저장 프로시저 실행, 알림 전송등에 활용된다
    • Chunk기반 스텝
      • 아이템 기반의 처리에서 사용된다
      • ItemReader, ItemProcessor, ItemWriter라는 3개의 주요 부분으로 구성 ( ItemProcessor는 필수가 아니다 )
  • 스프링 배치가 제공하는 인터페이스
    부모 패키지 인터페이스 설명
    org.springframework.batch.core Job ApplicationContext 내에 구성되는 잡 객체
    org.springframework.batch.core Step ApplicationContext 내에 구성되는 스텝을 나타내는 객체
    org.springframework.batch.core.step.tasklet Tasklet 트랜잭션 내에서 로직이 실행될 수 있는 기능을 제공하는 전략 인터페이스
    org.springframework.batch.item ItemReader<T> 스텝 내에서 입력을 제공하는 전략 인터페이스
    org.springframework.batch.item itemProcessor<T> 스텝 내에서 제공받는 개별 아이템에 업무 로직, 검증등을 적용하는 역할을 하는 인터페이스
    org.springframework.batch.item itemWriter<T> 스텝 내에서 아이템을 저장하는 전략 인터페이스
  • 스텝을 분리하므로 얻는 이득
    • 각 스텝이 독립적으로 처리될 수 있다
    • 유연성
      • 개발자가 복잡한 로직의 작업 플로우를 쉽게 구성할 수 있게 여러 빌더 클래스를 제공
    • 유지 보수성
      • 각 스텝의 코드는 독립적이므로 다른 스텝에 거의 영향을 미치지 않는다
      • 때문에 각 스텝마다 단위 테스트, 디버그, 변경을 할 수 있다
      • 여러 잡에서 구성된 스텝을 재사용할 수 있다 ( 스프링 빈처럼 )
    • 확장성
      • 스텝을 병렬로 실행하는 행위
      • 하나의 스텝 내에서 처리할 일을 여러 스레드로 병렬로 실행하는 행위 등 확장 가능
    • 신뢰성
      • 예외 발생시 해당 아이템의 처리를 재시도하거나 건너뛰기하는 등의 동작을 수행할 수 있다

 

3. Job 실행 

  • JobRepository
    • 스프링 배치 내에서 공유되는 주요 컴포넌트
    • 다양한 배치 수행과 관련된 수치 데이터(시작 시간, 종료 시간, 상태, 읽기/쓰기 횟수 등등 )뿐만 아니라 잡의 상태를 유지 관리
    • 일반적으로 관계형 데이터베이스를 사용
  • JobLauncher
    • 잡을 실행하는 역할
    • Job.execute 메서드를 호출하는 역할
    • 잡의 재실행 가능 여부 검증
    • 잡의 실행 방법(현재 쓰레드 or 스레드 풀을 사용하여 병렬로 할지)
    • 파라미터 유효성 검증 등의 처리를 수행
    • 스프링 부트 환경이라면 스프링 부트가 즉시 잡을 시작하는 기능을 제공하므로, 일반적으로는 직접 다룰 일이 없다
  • Job 실행 순서
    1. 잡은 실행하면 해당 잡은 구성된 각 스텝을 실행한다
    2. 각 스텝이 실행되면 JobRepository는 현재 상태로 갱신 ( 실행된 스텝, 현재 상태, 읽은 아이템, 처리된 아이템 수 등이 모두 JobRepository에 저장된다 )
    3. 여러 아이템으로 이뤄진 청크의 처리가 스텝 내에서 완료될 때, 스프링 배치는 JobRepository 내에 있는 JobExecution 또는 StepExecution을 현재 상태로 갱신
    4. 스텝은 ItemReader가 읽은 아이템 목록을 따라간다
    5. 스텝이 각 청크를 처리할 때마다, JobRepository 내 StemExecution의 스텝 상태가 업데이트된다
    6. 현재까지의 커밋 수, 시작 및 종료시간, 기타 다른 정보 등이 JobRepository에 저장된다
    7. 잡 또는 스텝이 완료되면, JobRepository 내에 있는 JobExecution, StepExecution이 최종 상태로 업데이트된다
  • JobInstance
    • "잡의 이름"과 "잡의 논리적 실행을 위해 제공되는 고유한 식별 파라미터 모음(JobParameters)"으로써 유일하게 존재
    • 즉 정의된 Job이 다른 파라미터로 실행될 때마다 새로운 JobInstance가 생성
    • 반대로 정의된 Job이 같은 파라미터로 실행되면 이미 생성된 JobInstance를 바라봄
  • JobExecution
    • 스프링 배치 잡의 실제 실행을 의미
    • 잡을 구동할 떄마다 매번 새로운 JobExecution을 얻게 된다
    • 하나의 JobInstance는 다수의 JobExecution을 가질 수 있다
      • 1번째 시도 실패 ( 새로운 JobInstance, JobExecution 생성 )
      • 2번째 시도 성공 ( 1번째와 같은 JobInstance, 새로운 JobExecution 생성 )
  • StepExecution
    • 스텝의 실제 실행을 나타낸다
    • JobExecution은 여러 개의 StepExection과 연관

 

4. 병렬화

  • 가장 단순한 배치 처리 아키텍처는 잡내의 스텝을 처음부터 끝까지 순서대로 단일 스레드에서 실행하는 것이다
  • 스프링 배치는 다양한 병렬화 방법을 제공한다
    • 다중 스레드 스텝을 통한 작업 분할
    • 전체 스텝의 병렬 실행
    • 비동기 ItemProcessor/ItemWriter 구성
    • 원격 청킹
    • 파티셔닝

4-1. 다중 스레드 스텝

  • 스프링 배치에서 잡은 청크라는 블록 단위로 처리되도록 구성되며, 각 청크는 각자 독립적인 트랜잭션으로 처리된다고 했다
  • 즉 1000개의 레코드가 있을 때 청크 단위를 50이라고 설정하면 (1..50)을 처리하고 커밋 (51..100)을 처리하고 커밋 ... 의 프로세스를 타게된다
  • 이 작업을 여러개의 스레드를 통해 병렬적으로 처리하여 처리량을 향상시킬 수 있다

4-2. 병렬 스텝

  • 구성되어있는 스텝 자체를 병렬로 실행하는 것

4-3. 비동기 ItemProcessor / ItemWriter

  • 어떤 상황에서는 스텝 내의 ItemProcessor가 병목현상이 올 수 있다
  • ItemReader가 제공하는 데이터를 가공하기 위해 복잡한 수학 계산을 수행하거나 원격 서비스를 호출해야 할 수도 있다
  • SynchonousItemProcessor는 ItemProcessor가 호출될 때마다 동일한 스레드에서 실행하게 만들어주는 ItemProcessor 구현체의 데코레이터이다
  • AsynchronousItemProcessor는 ItemProcessor 호출 결과를 반환하는 대신, 각 호출에 대해 java.utilconcurrent.Future를 반환한다
  • 청크 내에 반환된 Future 목록은 AsynchronousItemWriter로 전달되고 Future를 이용해 실제 결과를 얻어낸 후 이를 위임 ItemWriter에 전달한다

4-4. 원격 청킹

  • 원격 워커를 이용하여 처리하는 방식
  • 마스터에서 데이터를 읽고 원격 워커에서 처리한 다음 다시 마스터에게 전송하는 방식으로, 네트워크 사용량이 매우 많아지지만 속도 향상을 꾀할 수 있다 ( 실제 처리에 비해 I/O 비용이 적은 시나리오에 적합 )

4-5. 파티셔닝

  • 스프링 배치는 원격 파티셔닝(마스터 및 원격 워커를 사용), 로컬 파티셔닝(워커의 스레드 사용)을 모두 지원한다
  • 원격 파티셔닝을 사용하면 내구성 있는 통신 방법이 필요하지 않으며 마스터는 워커의 스텝 수집을 위한 컨트롤러 역할만 한다
  • 즉 각 워커의 스텝은 독립적으로 동작하며 마치 로컬로 배포된 것처럼 동일하게 구성된다

 

5. 프로젝트 초기 셋팅

  • 환경
    • IntelliJ
    • Java 8
    • SpringBatch
    • H2 ( JobRepository 인메모리 디비 )
    • Lombok
  • 샘플 코드
    // HelloWorldApplication.class
    @RequiredArgsConstructor
    @EnableBatchProcessing
    @Configuration
    public class HelloWorldApplication {
    
        private final JobBuilderFactory jobBuilderFactory;
        private final StepBuilderFactory stepBuilderFactory;
    
        @Bean
        public Job helloWorldJob() {
            return this.jobBuilderFactory.get("helloWorldJob")
                    .start(helloWorldStep())
                    .build();
        }
    
        @Bean
        public Step helloWorldStep() {
            return this.stepBuilderFactory.get("helloWorldStep")
                    .tasklet((contribution, chunkContext) -> {
                        System.out.println("Hello, World!");
                        return RepeatStatus.FINISHED;
                    })
                    .build();
        }
    }​

    • Job이 하나일때는 따로 Program Argument를 안줘도 바로 실행된다
  • @EnableBatchProcessing
    • 스프링 배치가 제공하는 애너테이션
    • 배치 인프라스트럭처를 부트스트랩하는데 사용되며, 인프라스트럭처를 구성하기 위한 대부분의 스프링 빈 정의를 제공한다 ( 아래는 제공되는 스프링 빈들 )
      • JobRepository: 실행 중인 Job의 상태를 기록하는데 사용
      • JobLauncher: 잡을 구동하는 데 사용
      • JobExplorer: JobRepository를 사용해 읽기 전용 작업을 수행하는 데 사용됨
      • JobRegistry: 특정한 런처 구현체를 사용할 때 잡을 찾는 용도로 사용
      • PlatfromTransactionManager: 잡 진행 과정에서 트랜잭션을 다루는 데 사용됨
      • JobBuilderFactory: 잡을 생성하는 빌더
      • StepBuilderFactory: 스텝을 생성하는 빌더
  • Step을 정의할 때 RepeatStatus.FINISHED를 반환했다 ( 해당 반환값이 CONTINUABLE이면 영원히 반복한다 )
  • 기본적으로 SpringBoot는 구성된 ApplicationContext 내에서 찾은 모든 잡을 실행시킨다 ( 후에 특정 잡만 실행시키게 프로퍼티 설정을 하면 된다 )
  • 동작 순서
    • SpringBoot 구동
    • ApplicationContext 생성
    • JobLauncherCommandLineRunner 실행
    • 정의된 잡을 실행
    • 잡은 각 단계의 스텝을 차례대로 실행 ( 스텝을 실행할 때 트랜잭션또한 시작 )
728x90
반응형