스프링 배치와 스케줄러의 차이

yeop·2023년 6월 1일

✔️ 배치란?

  • 사용자와의 상호작용 없이 여러 작업을 미리 정해진 순서에 따라 중단 없이 처리하는 것
  • 배치의 특징
    - 대용량 데이터
    • 자동화
    • 견고성: 잘못된 데이터를 충돌/중단 없이 처리할 수 있어야 합니다.
    • 신뢰성: 로깅, 알림 등을 통해 무엇이 잘못되었는지를 추적할 수 있어야 합니다.
    • 성능: 지정한 시간 안에 처리를 완료하거나 동시에 실행되는 다른 프로그램을 방해하지 않아야 합니다.

스프링 배치 구성

배치 플로우

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

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

JobInstance

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

JobExecution

  • JobExecution은 JobIstance에 대한 한 번의 실행을 나타내는 객체입니다.
    JobExecution은 JobInstance, 배치 실행 상태, 시작 시간, 끝난 시간, 실패했을 때 메시지 등의 정보를 담고 있습니다.

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를 사용해서 저장한 타입의 리스트를 매게변수로 받습니다.

✔️ 스프링 배치를 이용한 휴먼 계정 처리

@Configuration
@RequiredArgsConstructor
@Slf4j
public class InactiveUserJobConfiguration {

    private final UserRepository userRepository;
    private final StepBuilderFactory stepBuilderFactory;
    private final JobBuilderFactory jobBuilderFactory;

    @Bean
    public Job inactiveUserJob(JobBuilderFactory jobBuilderFactory, Step inactiveJobStep) {
        return jobBuilderFactory.get("inactiveUserJob")
            .preventRestart()
            .incrementer(new RunIdIncrementer())
            .start(inactiveJobStep)
            .build();
    }

    @Bean
    public Step inactiveJobStep(StepBuilderFactory stepBuilderFactory) {
        return stepBuilderFactory.get("inactiveUserStep")
            .<User, User> chunk(10)
            .reader(inactiveUserReader())
            .processor(inactiveUserProcessor())
            .writer(inactiveUserWriter())
            .build();
    }

    @Bean
    @StepScope
    public QueueItemReader<User> inactiveUserReader() {
        List<User> targetUsers =
            userRepository.findBylastModifiedAtBeforeAndStatusEquals(
                LocalDateTime.now().minusYears(1),
                true);
        log.info("InActive Target User Count: " + targetUsers.size());

        return new QueueItemReader<>(targetUsers);
    }

    @Bean
    @StepScope
    public ItemProcessor<User, User> inactiveUserProcessor() {
        return User::toInActive;
    }

    @Bean
    @StepScope
    public ItemWriter<User> inactiveUserWriter() {
        return (userRepository::saveAll);
    }
}
  • 스프링 배치를 사용하기 위해서는 DB에 배치 처리를 위한 테이블들이 필요합니다.

  • schema.mysql.sql 파일을 통해 테이블 생성 후 실행 가능
    Spring Batch 개발기 ( 4. MetaData테이블 )

  • 이후 스케줄러를 적용하여 ApplicationContext에 있는 Job bean을 가져와 JobLauncher로 실행시킬 수 있습니다.

✔️ 스케쥴러란?

  • 특정한 시간에 등록한 작업을 자동으로 실행시키는 것
  • Spring Scheduler, Quartz

휴먼 계정 처리 - 스케쥴러 선택 이유

  • 스케쥴러는 한 번에 많은 양의 데이터를 처리하려면 성능 이슈가 발생할 수 있기 때문에 대용량 데이터 처리에는 부적합합니다. 하지만 현재 서비스는 출시 직후 예상 유저가 약 200명이기 때문에 간단한 스케쥴링 작업에 적합합니다.

0개의 댓글