Spring Batch 정리

유기환·2020년 4월 22일
3

1. 배경 지식

1-1. 배치 처리에서 스프링 배치를 써야하는 이유?

  • 대용량 데이터 처리에 최적화 되어 고성능을 발휘한다.
  • 효과적인 로깅, 통계 처리, 트랜잭션 관리 등 재사용 가능한 필수 기능을 지원한다.
  • 수동으로 처리하지 않도록 자동화되어 있다.
  • 예외사항과 비정상 동작에 대한 방어 기능이 있다.
  • 스프링 부트 배치의 반복되는 작업 프로세스를 이해하면 비즈니스 로직에 집중 할 수 있다.

1-2. 스프링 부트 배치 주의 사항

  • 가능하면 단순화해서 복잡한 구조와 로직을 피해야한다.
  • 데이터를 직접 사용하는 작업이 빈번하게 일어나므로 데이터 무결성을 유지하는 유효성 검사 등의 방어책이 있어야합니다.
  • 배치 처리시 시스템 I/O 사용을 최소화해야 한다. 잦은 I/O로 데이터 베이스 커넥션과 네이트워크 비용이 커지면서 성능에 영향을 줄 수 있이 때문입니다. 따라서 가능하면 한번에 데이터를 조회하여 메모리에 저장해두고 처리를 한 다음, 그결과를 한번에 데이터베이스에 저장하는 것이 좋습니다.
  • 일반적으로 같은 서비스에 사용되는 웹, API, 배치, 기타 프로젝트들은 서로 영향을 줍니다. 따라서 배치 처리가 진행되는 동안 다른 프로젝트 요소에 영향을 주는 경우가 없는지 주의를 기울여야합니다.
  • 스프링 부트 배치는 스케쥴러를 제공하지 않습니다. 배치 처리 기능만 제공하며 스케줄링 기능은 스프링에서 제공하는 쿼츠 프레임워크(Quartz Framework)를 이용해야합니다. 리눅스 crontab 명령은 가장 간단하게 사용할 수 있지만 이는 추천하지 않습니다. crontab의 경우 각 서버마다 따로 스케줄링을 관리해야함

2. 스프링 부트 배치 이해

  1. 읽기(read) : 데이터 저장소(일반적으로 데이터베이스)에서 특정 데이터 레코드를 읽습니다.
  2. 처리(processing) : 원하는 방식으로 데이터를 가공/처리합니다.
  3. 쓰기(wirte) : 수정된 데이터를 다시 저장소(데이터베이스)에 저장합니다.

읽기 -> 처리 -> 쓰기

Job과 Step 1:M
Step과 ItemReader, ItemProcessor, ItemWriter 1:1

즉, Job 하나의 일(Job)을 두고 여러 단계(step)을 가지고 있음

2-1. 용어 정리

2-1-1. Job

Job은 배치 처리 과정을 하나의 단위로 만들어 표현한 객체입니다. 또한 전체 배치 처리에 있어 항상 최상단 계층에 있습니다.

위에서 하나의 Job(일감) 안에는 여러 Step(단계)이 있다고 설명했던 바와 같이 스프링 배치에서 Job 객체는 여러 Step 인스턴스를 포함하는 컨테이너 입니다

Job 객체를 만드는 빌더는 여러 개 있습니다.

여러 빌더를 통합하여 처리하는 공장인 JobBuilderFactory로 원하는 Job을 쉽게 만들수 있습니다.

JobBuilderFactory 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
public class JobBuilderFactory {
 
    private JobRepository jobRepository;
 
    public JobBuilderFactory(JobRepository jobRepository) {
        this.jobRepository = jobRepository;
    }
 
    public JobBuilder get(String name) {
        JobBuilder builder = new JobBuilder(name).repository(jobRepository);
        return builder;
    }
}
cs
  • JobBuilderFactory는 JobBuilder를 생성할 수 있는 get() 메서드를 포함하고 있습니다.
    get() 메서드 내부를 들여다보면 JobBuilderFactory가 새로운 JobBuilder를 생성해서 반환하는 것을 확인할 수 있습니다.
  • JobBuilderFactory에 get() 메서드를 호출 할 때마다 새로운 빌더가 생성됩니다.

SimpleJobBulider를 이용한 Job 생성 예제

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class InactiveUserJobConfig {
    @Bean
    public Job inactiveUserJob(JobBuilderFactory jobBuilderFactory,
            Step inactiveUserJobStep) { // (1)
 
        return jobBuilderFactory.get("inactiveUserJob")
                .preventRestart()  // (2)
                .start(inactiveUserJobStep)  // (3)    
                .build();
    }
}
cs
  • JobBuilderFactory의 get() 메서드에 "simpleJob" 문자열을 파라미터로 넘긴다
  • "simpleJob"이라는 이름을 가진 Job을 생성할 수 있는 JobBuilder 객체 인스턴스가 반환
  • simpleStep() 메소드는 아주 간단한 Step인스턴스르 생성하여 반환하는 메서드라 가정
  • SimpleJobBuilder의 builder의 build() 메서드를 호출하여 빌드
  • "simpleJob"이라는 이름을 가진 Job이 생성되어 반환

2-1-2. JobInstance

  • JobInstance는 배치에서 Job이 실행될 때 하나의 Job 실행 단위입니다.
  • JobInstance는 여러 개의 JobExecution(JobInstance에 대한 한번의 실행을 나타내는 객체)을 가지고 있을 수 있습니다.
  • 오늘 Job을 실행했는데 실패했다면 다음날 동일한 JobInstance를 가지고 또 실행합니다. Job 실행이 실패하면 JobInstance가 끝난 것으로 간주하지 않기 때문입니다.
  • JobInstance는 어제의 실패한 JobExecution과 오늘의 성공한 JobExcution 두 개를 가지게 됩니다.

2-1-3. JobExecution

  • JobExecution은 JobInstance에 대한 한 번의 실행을 나타내는 객체입니다.

2-1-4. JobParameters

  • JobParameters는 Job이 실행될 때 필요한 파라미터들을 Map 타입으로 저장하는 객체입니다.
  • 하나의 Job이 생성될 때, 시작 시간등의 정보를 파라미터로 해서 하나의 JobInstance를 생성해서 JobInstance와 JobParameters는 1:1 관계를 유지한다.
  • 파라미터 타입은 String, Long, Date, Double을 사용할 수 있습니다.

2-1-5. Step

  • Step은 실질적인 배치 처리를 정의하고 제어하는데 필요한 모든 정보가 들어 있는 도메인 객체입니다.
  • Job을 처리하는 실직적인 단위로 쓰입니다. 모든 Job에는 1개 이상의 step이 있어야합니다.

2-1-6. StepExecution

Job에 JobExecution Job실행 정보가 있다면 Step에는 StepExecution이라는 Step 실행 정보를 담는 객체가 있습니다.

2-1-7. JobRepository

  • JobRepository는 배치 처리 정보를 담고 있는 매커니즘입니다. 어떤 Job이 실행되었으면 몇 번 실행되었고 언제 끝났는지 등 배치 처리에 대한 메타데이터를 저장합니다.
  • 예를들어 Job 하나가 실행되면 JobRepository에서는 배치 실행에 관련된 정보를 담고 있는 도메인 JobExecution을 생성합니다.
  • JobRepository는 Step의 실행 정보를 담고 있는 StepExecution도 저장소에 저장하여 전체 메타데이터를 저장/관리하는 역할을 수행합니다.

2-1-8. JobLauncher

JobLauncher는 Job. JobParamerters와 함께 배치를 실행하는 인터페이스입니다.

2-1-9. ItemReader

ItemReader는 Step의 대상이 되는 배치 데이터를 읽어오는 인터페이스입니다. File, Xml Db등 여러 타입의 데이터를 읽어올 수 있습니다.

2-1-10. ItemProcessor

ItemProcessor는 ItemReader로 읽어 온 배치 데이터를 변환하는 역할을 수행합니다. 이것을 분리하는 이유는 다음과 같습니다.
비즈니스 로직의 분리 : ItemWriter는 저장 수행하고, ItemProcessor는 로직 처리만 수행해 역할을 명확하게 분리합니다.
읽어온 배치 데이터와 씌여질 데이터의 타입이 다를 경우에 대응할 수 있기 때문입니다.

2-1-11. ItemWriter

ItemWriter는 배치 데이터를 저장합니다. 일반적으로 DB나 파일에 저장합니다.
ItemWriter도 ItemReader와 비슷한 방식을 구현합니다. 제네릭으로 원하는 타입을 받고 write() 메서드는 List를 사용해서 저장한 타입의 리스트를 매게변수로 받습니다.

참고

Yum Blog
https://cheese10yun.github.io/spring-batch-basic/#null
처음 배우는 스프링 부트. 2
http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791162241264&orderClick=LAA&Kc=

0개의 댓글