Spring

SpringBatch

ZzangHo 2022. 2. 7. 21:52
728x90

SpringBatch란?

배치처리 기능을 구현하는데 사용되는 프레임워크로 설정이 간편하며 빠르게 배치 프로그램을 제작 할 수 있다.

 

SpringBatch를 써야하는 이유?

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

주의 사항

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

SpringBatch 구조

배치처리의 경우 데이터 읽기 -> 데이터 처리 -> 데이터 쓰기의 흐름을 갖고 있다. 

다음 그림은 스프링 배치의 구조인데 그림을 보면 제일 오른쪽에 ItemReader(데이터 읽기), 데이터 처리(ItemProcessor), 데이터 쓰기(ItemWriter)가 있는 것을 볼 수 있습니다.

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

SpringBatch 용어

Job

  • Job은 배치 처리 과정을 하나의 단위로 만들어 포현한 객체입니다. 또한 전체 배치 처리에 있어 항상 최상단 계층에 있습니다.
  • 위에서 하나의 Job(일감) 안에는 여러 Step(단계)이 있다고 설명했던 바와 같이 스프링 배치에서 Job 객체는 여러 Step 인스턴스를 포함하는 컨테이너 입니다
  • Job 객체를 만드는 빌더는 여러 개 있습니다. 여러 빌더를 통합하여 처리하는 공장인 JobBuilderFactory로 원하는 Job을 쉽게 만들수 있습니다.
public class JobBuilderFactory {
    private JobRepostiroy jobrepository;

    public JobBuilderFactory(JobRepository jobRepository){
        this.jobrepository = jobrepository;
    }

    public JobBuilder get(String name){
        JobBuilder builder = new JobBuilder(name).repository(jobrepository);
        return builder;
    }
}
  • JobBuilderFactory는 JobBuilder를 생성할 수 있는 get() 메서드를 포함하고 있습니다. get()메서드는 새로운 JobBuilder를 생성해서 반환하는 것을 확인할 수있습니다.
  • JobBuilderFactory에서 생성되는 모든 JobBulder가 레포지토리를 사용합니다.
  • JobBuilderFactory는 JobBuilder를 생성하는 역할만 수행합니다. 이렇게 생성된 JobBuilder를 이용해서 Job을 생성해야 하는데, 그렇다면 JobBuilder의 역할은 무엇인지 JobBuilder의 메서드를 통해 기능을 알아보겠습니다.
public SimpleJobBuilder start(Step step) {
    return (new SimpleJobBuilder(this)).start(step);
}

public JobFlowBuilder start(Flow flow) {
    return (new FlowJobBuilder(this)).start(flow);
}

public JobFlowBuilder flow(Step step) {
    return (new FlowJobBuilder(this)).start(step);
}
  • JobBuilder는 직접적으로 Job을 생성하는 것이 아니라 별도의 구체적 빌더를 생성하여 변환하여 경우에 따라 Job 생성 방법이 모두 다를 수 있는 점을 유연하게 처리할 수 있습니다.

JobInstance

  • JobInstance는 배치 처리에서 Job이 실행될 때 하나의 Job 실행 단위입니다. 만약 하루에 한 번 씩 배치의 Job이 실행된다면 어제와 오늘 실행 각각 Job을 JobInstance라고 부를 수 있습니다.
  • 각각의 JobInstance는 하나의 JobExecution을 갖는 것은아닙니다. 오늘 Job이 실행 했는데 실패했다면 다음날 동일한 JobInstance를 가지고 또 실행합니다.
  • Job 실행이 실패하면 JobInstance가 끝난것으로 간주하지 않기 때문입니다. 그렇다면 JobInstance는 어제 실패한 JobExecution과 오늘의 성공한 JobExecution 두 개를 가지게 됩니다. 즉 JobExecution 는 여러 개 가질 수 있습니다.

JobExecution

  • JobExecution은 JobIstance에 대한 한 번의 실행을 나타내는 객체입니다.
  • 만약 오늘 Job이 실패해 내일 다시 동일한 Job을 실행하면 오늘/내일의 실행 모두 같은 JobInstance를 사용합니다.
  • 실제로 JobExecution 인터페이스를 보면 Job 실행에 대한 정보를 담고 있는 도메인 객체가 있습니다. JobExecution은 JobInstance, 배치 실행 상태, 시작 시간, 끝난 시간, 실패했을 때 메시지 등의 정보를 담고 있습니다. JobExecution 객체 안에 어떤 실행 정보를 포함 하고 있습니다.

JobParameters

  • JobParameters는 Job이 실행될 때 필요한 파라미터들은 Map 타입으로 지정하는 객체 입니다.
  • JobParameters는 JobInstance를 구분하는 기준이 되기도 합니다.
  • JobParameters와 JobInstance는 1:1 관계입니다.

Step

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

StepExecution

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

JobRepository

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

JobLauncher

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

ItemReader

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

ItemProcessor

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

ItemWriter

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

 

참고

https://cheese10yun.github.io/spring-batch-basic/#null

https://velog.io/@kihwanyu/Spring-Batch-%EC%A0%95%EB%A6%AC

'Spring' 카테고리의 다른 글

application.yml 여러개로 나누기  (0) 2022.12.14
stream API와 for-loop 성능차이  (0) 2022.02.07
SpringBatch 전용 DB 테이블  (0) 2022.02.07
application.yml로 환경 나누기  (0) 2022.01.28