요즘은 매일 Batch test가 진행되고 있다. 여신은 유이자 이행, 상환 등등의 배치 프로세스가 중요한 부분을 차지한다. 배치에 대해서 알아보자!
스프링 배치 (Spring Batch)
- 배치 == 일괄처리. 즉 일련의 작업을 정해진 로직으로 수행하는 것이다.
배치를 사용하는 이유
- 대용량 비즈니스 데이터를 복잡한 작업으로 처리해야 하는 경우
- 특정한 시점에 스케줄링된 자동화된 작업이 필요한 경우
- 대용량 데이터 포맷을 변경하거나 유효성 검사를 하는 등의 작업을 트랜잭션 안에서 처리하고 기록해야 하는 경우
일반적인 배치 사용 시나리오
- 데이터베이스, 파일, 큐 등에서 데이터를 read :
ItemReader
- 데이터를 정의한 방식으로 process :
ItemProcessor
- 처리된 데이터를 DB에 write :
ItemWriter
- 반복적으로 트랜잭션 단위로 데이터를 처리할 수 있다.
- 데이터 처리에 대한 비즈니스 로직에만 집중하여 배치 프로세스를 작성할 수 있다.
Batch의 구성요소
Job
- 전체 배치 프로세스를 캡슐화하는 엔티티
- XML, Java로 설정할 수 있다.
- Step 인스턴스의 컨테이너 역할을 하기 때문에 생성하기 전에 인스턴스를 전달받는다.
- 비즈니스 로직을 가진 여러 Step들을 결합하고, 모든 step에 전역 속성을 설정할 수 있다.
- 하나의 Job에는 여러 Step이 있다. 각 Step을 배치의 기본 흐름대로 구현한다. (ItemReader -> ItemProcessor -> ItemWriter)
JobBuilderFactory
(여러 빌더를 처리하는 공장)로 원하는 Job을 만들 수 있다.
필요한 구성요소
- 작업의 간단한 이름
- Step 인스턴스의 정의 및 순서
- 작업을 다시 시작할 수 있는지 여부
용어와 메소드
1. JobBuilderFactory
- jobBuilderFactory.get()으로 JobBuilder 생성 가능
- jobBuilderFactory.get(“jobName”)
2. JobBuilder
- jobBuilderFactory로 JobBuilder 생성 -> 생성된 JobBuilder로 Job 생성
- SimpleJobBuilder start(Step step);
- step 추가해서 가장 기본이 되는
SimpleJobBuilder
생성
- step 추가해서 가장 기본이 되는
- JobFlowBuilder start(Flow flow);
- Flow를 실행할
JobFlowBuilder
생성
- Flow를 실행할
- JobFlowBuilder flow(Step step);
- Step을 실행할
JobFlowBuilder
생성
- Step을 실행할
3. JobInstance
- 배치에서 Job이 실행될 때 하나의 Job 실행단위
4. JobExecution
- JobInstance에 대한 한 번의 실행을 나타내는 객체
- Job 실행에 대한 정보를 담고 있는 도메인 객체
- JobInstance, 배치 실행 상태, 시작 시간, 끝난 시간, 실패했을 때의 메세지 정보 등을 담고 있다.
- 오늘 Job이 실패해 내일 다시 동일한 Job실행시 동일한 Instance를 사용한다.
5. JobExecutionContext
- Job 실행 중 개발자가 지속적으로 유지되었으면 하는 데이터를 저장하는 데이터 컬렉션
- 프레임워크에 의해 유지, 관리되고 Job이 실행되는 중간 커밋 지점에서 주기적으로 저장된다.
- Job 실행 중 치명적인 오류나 컴퓨터가 다운된 경우에도 상태를 유지할 수 있다.
6. JobRunner
- 외부 요청에 의해 작업 실행을 담당하는 클래스
- JobLauncher의 인스턴스화 수행
- run()
7. JobParameters
- 배치 Job이 실행될 때 필요한 파라미터 셋을 가지고 있는 객체
- JobParameters : JobInstance = 1:1 관계
코드 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Slf4j // log 사용을 위한 lombok 어노테이션
@RequiredArgsConstructor // 생성자 DI를 위한 lombok 어노테이션
@Configuration
public class SimpleJobConfiguration {
private final JobBuilderFactory jobBuilderFactory; // 생성자 DI 받음
private final StepBuilderFactory stepBuilderFactory; // 생성자 DI 받음
@Bean
public Job simpleJob1() {
return jobBuilderFactory.get("simpleJob1") // simpleJob1이라는 이름의 Batch Job 생성. Builder를 통해 이름 지정
.start(simpleStep1())
.build();
}
@Bean
public Step simpleStep1() {
return stepBuilderFactory.get("simpleStep1") // simpleStep1이라는 이름의 Batch Step 생성
.tasklet((contribution, chunkContext) -> { // step 안에서 수행될 기능 명시
log.info(">>>>> This is Step1");
return RepeatStatus.FINISHED;
})
.build();
}
}
- simpleJob1은 simpleStep1을 품고 있다.
Step
- 실질적인 배치 처리를 정의하고 제어하는데 필요한 모든 정보가 들어 있는 도메인 객체
- Job을 처리하는 실질적인 단위
- 모든 Job은 1개 이상의 Step을 가진다.
용어와 메소드
1. StepExecution
- Step 실행 정보를 담는 객체
- 각각의 Step이 실행될 때마다 StepExceution이 생성된다.
JobRepository
- 배치 처리 과정 중 프레임워크에서 사용하는 메타데이터 정보를 액세스하는 Facade 클래스
JobLauncher
- 작업의 시작과 실제 실행을 관리하는 인터페이스
- JobRunner에 의해 인스턴스화된다.
- JobParameters와 함께 배치를 실행하는 주체다.
Chunk
- Chunk: 아이템이 트랜잭션에서 커밋되는 수. read한 데이터 수가 지정한 chunk단위와 일치하면 write를 수행하고 트랜잭션을 커밋한다.
- Chunk oriented processing : 트랜잭션 경계 내에서 청크 단위로 데이터를 읽고 생성하는 프로그래밍 기법
- Chunk 지향 프로세싱을 하는 이유
- chunk로 나누지 않았을 때는 하나만 실패해도 성공한 다른 모든 데이터가 롤백처리 된다.
- 청크 단위를 10개로 지정하면 처리 중 실패시 해당 청크(10개의 데이터)만 롤백처리한다.
Tasklet
- 임의의 step을 실행할 때 하나의 작업으로 처리하는 방식
- Tasklet: 읽기, 처리, 쓰기를 단일 작업으로 만드는 개념(chunk는 읽기, 처리, 쓰기가 나누어져 있음)
- 배치의 특정 작업을 개발하기 위해 step의 기본 단위를 만들 수 있는 클래스
2022/07/06 추가한 내용: simple batch와 connected batch의 차이에 대해 알고 싶다. connected batch는 전 건을 순차적으로 처리하는 simple batch와 다르게 한 번에 일정한 단위의 데이터만을 commit하고 다음 데이터를 불러오는 것 같은데, 확실히는 모르겠다.
reference
[스프링/Spring] Batch 소개와 간단한 예제
[스프링/Spring] Batch 구조와 구성 요소
2. Spring Batch 가이드 - Batch Job 실행해보기
[Spring] 스프링 부트 배치 기본 지식과 설정: 용어 정리, Chunk 지향 프로세싱/Tasklet & Listener 설정 / Step 흐름 제어