[Spring] Spring Batch - 청크 방식

이다혜·2024년 1월 16일
0

Spring

목록 보기
26/27

Spring Batch는 대용량 데이터를 효율적으로 처리하기 위한 프레임워크이다.

📌 청크(Chunk)

Chunk란 여러 개의 아이템을 묶은 하나의 덩어리, 블록을 의미한다.
한 번에 모든 행을 읽고 처리하고 쓰는 것이 아니라, 한 번에 고정 된 양의 레코드를 읽고 처리하는 방식이다.

📌 구성요소

청크 방식은 크게 세 가지 구성 요소로 이루어져 있다.

✏ ItemReader

  • 데이터를 읽어오는 역할을 한다.
  • 설정된 청크 크기만큼의 데이터를 읽어온다.

✏ ItemProcessor

  • ItemReader가 읽어온 데이터를 가공하거나 변환하는 역할을 한다.
  • 각각의 데이터에 대해 비지니스 로직을 수행하고, 필요에 따라 새로운 형태의 데이터로 변환한다.

✏ ItemWriter

  • ItemProcessor에서 처리된 데이터를 실제 저장하거나 외부 시스템에 전달하는 역할을 한다.
  • 설정된 청크 크기만큼의 데이터를 한 번에 쓰기 작업을 수행한다.

💻 실습

Product 데이터를 기반으로 Log를 생성하는 배치 작업을 실행하는 코드 실습을 해보자

📍 Job 설정

@Bean
    public Job makeProductLogJob(JobRepository jobRepository, Step makeProductLogStep1) {
        return new JobBuilder("makeProductLogJob", jobRepository)
                .start(makeProductLogStep1)
                .incrementer(new RunIdIncrementer())
                .build();
    }
  • Job을 생성하는 메서드
  • JobBuilder를 사용해서 'makeProductLogJob'이라는 이름의 Job을 빌드한다.
  • .start() : 해당 Job의 첫 번째 Step을 설정한다.

📍 Step 설정

 	@JobScope
    @Bean
    public Step makeProductLogStep1(
            JobRepository jobRepository,
            ItemReader<Product> step1Reader,
            ItemProcessor<Product, ProductLog> step1Processor,
            ItemWriter<ProductLog> step1Writer,
            PlatformTransactionManager platformTransactionManager
    ) {
        return new StepBuilder("makeProductLogStep1Tasklet", jobRepository)
                .<Product, ProductLog>chunk(CHUNK_SIZE, platformTransactionManager)
                .reader(step1Reader)
                .processor(step1Processor)
                .writer(step1Writer)
                .build();
    }
  • Step을 생성하는 메서드
  • @JobScope : Job 내에서 관리됨을 의미한다.
  • <Product, ProductLog> : ItemReader, ItemProcessor, ItemWriter의 입력 및 출력 유형을 나타낸다.
  • .chunk() : 청크 방식으로 배치를 처리한다.
  • CHUNK_SIZE : 사이즈 만큼의 데이터를 한 번에 처리한다.

📍 ItemReader 설정

	@StepScope
    @Bean
    public ItemReader<Product> step1Reader() {
        return new RepositoryItemReaderBuilder<Product>()
                .name("step1Reader")
                .repository(productRepository)
                .methodName("findAll")
                .pageSize(CHUNK_SIZE)
                .sorts(Collections.singletonMap("id", Sort.Direction.ASC))
                .build();
    }
  • Product 엔티티를 읽어오는 ItemReader를 생성한다.
  • .name() : ItemReader의 이름을
  • .repository() : 사용할 Spring Data Repository를 설정한다.
  • .methodName() : 리포지터리에서 사용할 메서드를 설정한다. 모든 데이터를 가져오기 위해 findAll을 썼다.
  • .pageSize() : 한 번에 가져올 데이터의 수
  • .sorts() : 데이터를 읽어올 때 정렬 기준을 설정한다.

📍 ItemProcessor 설정

@StepScope
    @Bean
    public ItemProcessor<Product, ProductLog> step1Processor() {
        return product -> ProductLog
                .builder()
                .product(product)
                .name(product.getName())
                .build();
    }
  • @StepScope : Step 내에서 빈이 생성되고 관리된다. 즉, Step 실행 시에만 빈이 생성되고 Step이 끝나면 빈이 소멸된다.
  • Product를 ProductLog로 변환하는 로직

📍 ItemWriter 설정

@StepScope
    @Bean
    public ItemWriter<ProductLog> step1Writer() {
        return items -> items.forEach(item -> {
            productLogRepository.save(item);
        });
    }
  • ProductLog를 저장한다.

0개의 댓글