๊ด€๋ฆฌ ๋ฉ”๋‰ด

๐‘†๐‘ข๐‘›๐‘ โ„Ž๐‘–๐‘›๐‘’ ๐‘Ž๐‘“๐‘ก๐‘’๐‘Ÿ ๐‘Ÿ๐‘Ž๐‘–๐‘›โœง

[Spring] Batch ๋ณธ๋ฌธ

Batch

  • ํฐ ๋‹จ์œ„์˜ ์ž‘์—…์„ ์ผ๊ด„ ์ฒ˜๋ฆฌ
  • ๋Œ€๋ถ€๋ถ„ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๋งŽ๊ณ  ๋น„ ์‹ค์‹œ๊ฐ„์„ฑ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ
    • ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ๊ณ„์‚ฐ, ์ •์‚ฐ, ํ†ต๊ณ„, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ๋ณ€ํ™˜ ๋“ฑ
  • ์ปดํ“จํ„ฐ ์ž์›์„ ์ตœ๋Œ€๋กœ ํ™œ์šฉ
    • ์ปดํ“จํ„ฐ ์ž์› ์‚ฌ์šฉ์ด ๋‚ฎ์€ ์‹œ๊ฐ„๋Œ€์— ๋ฐฐ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜
    • ๋ฐฐ์น˜๋งŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋˜ ๋‹ค๋ฅธ ์ปดํ“จํ„ฐ ์ž์›์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ ๋ณด๋‹จ, ์Šค์ผ€์ค„๋Ÿฌ์™€ ๊ฐ™์€ ์‹œ์Šคํ…œ์— ์˜ํ•ด ์‹คํ–‰๋˜๋Š” ๋Œ€์ƒ
    • ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋งค์ผ ์˜ค์ „ 10์‹œ์— ๋ฐฐ์น˜ ์‹คํ–‰, ๋งค์ฃผ ์›”์š”์ผ 12์‹œ ๋งˆ๋‹ค ์‹คํ–‰

 

 

 

Job

  • Job์€ JobLauncher์— ์˜ํ•ด ์‹คํ–‰
  • Job์€ ๋ฐฐ์น˜์˜ ์‹คํ–‰ ๋‹จ์œ„๋ฅผ ์˜๋ฏธ
  • Job์€ N๊ฐœ์˜ Step์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ๋ฆ„(Flow)์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค๋ฉด, A Step ์‹คํ–‰ ํ›„ ์กฐ๊ฑด์— ๋”ฐ๋ผ B Step ๋˜๋Š” C Step์„ ์‹คํ–‰ ์„ค์ •

Step

  • Step์€ Job์˜ ์„ธ๋ถ€ ์‹คํ–‰ ๋‹จ์œ„์ด๋ฉฐ, N๊ฐœ๊ฐ€ ๋“ฑ๋ก๋ผ ์‹คํ–‰๋œ๋‹ค.
  • Step์˜ ์‹คํ–‰ ๋‹จ์œ„๋Š” ํฌ๊ฒŒ 2๊ฐ€์ง€๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
    1. Chunk ๊ธฐ๋ฐ˜ : ํ•˜๋‚˜์˜ ํฐ ๋ฉ์–ด๋ฆฌ๋ฅผ n๊ฐœ์”ฉ ๋‚˜๋ˆ ์„œ ์‹คํ–‰
    2. Task ๊ธฐ๋ฐ˜ : ํ•˜๋‚˜์˜ ์ž‘์—… ๊ธฐ๋ฐ˜์œผ๋กœ ์‹คํ–‰

  • ๋ฐฐ์น˜ ์‹คํ–‰์„ ์œ„ํ•œ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ํ…Œ์ด๋ธ”
  • BATCH_JOB_INSTANCE
    • Job์ด ์‹คํ–‰๋˜๋ฉฐ ์ƒ์„ฑ๋˜๋Š” ์ตœ์ƒ์œ„ ๊ณ„์ธต์˜ ํ…Œ์ด๋ธ”
    • job_name๊ณผ job_key๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋‚˜์˜ row๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ, ๊ฐ™์€ job_name๊ณผ job_key๊ฐ€ ์ €์žฅ๋  ์ˆ˜ ์—†๋‹ค.
    • job_key๋Š” BATCH_JOB_EXECUTION_PARAMS์— ์ €์žฅ๋˜๋Š” Parameter๋ฅผ ๋‚˜์—ดํ•ด ์•”ํ˜ธํ™”ํ•ด ์ €์žฅํ•œ๋‹ค.
  • BATCH_JOB_EXECUTION
    • Job์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์‹œ์ž‘/์ข…๋ฃŒ ์‹œ๊ฐ„, job ์ƒํƒœ ๋“ฑ์„ ๊ด€๋ฆฌ
  • BATCH_JOB_EXECUTION_PARAMS
    • Job์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ์ž…๋œ parameter ์ •๋ณด ์ €์žฅ
  • BATCH_JOB_EXECUTION_CONTEXT
    • Job์ด ์‹คํ–‰๋˜๋ฉฐ ๊ณต์œ ํ•ด์•ผํ•  ๋ฐ์ดํ„ฐ๋ฅผ  ์ง๋ ฌํ™”ํ•ด ์ €์žฅ
  • BATCH_STEP_EXECUTION
    • Step์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ๋˜๋Š” ์‹คํ–‰๋œ ๊ฒฐ๊ณผ ์ €์žฅ
  • BATCH_STEP_EXECUTION_CONTEXT
    • Step์ด ์‹คํ–‰๋˜๋ฉฐ ๊ณต์œ ํ•ด์•ผํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•ด ์ €์žฅ

 

package com.example.temp_deletethis.part1;

import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@Slf4j
public class HelloConfiguration {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    public HelloConfiguration(JobBuilderFactory jobBuilderFactory,
                              StepBuilderFactory stepBuilderFactory) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
    }

    @Bean
    public Job helloJob() {
        return jobBuilderFactory.get("helloJob")
                .incrementer(new RunIdIncrementer())
                .start(this.helloStep())
                .build();
    }

    @Bean
    public Step helloStep() {
        return stepBuilderFactory.get("helloStep")
                .tasklet((contribution, chunkContext) -> {
                    log.info("hello spring batch");
                    return RepeatStatus.FINISHED;
                }).build();
    }
}

Job์€ batch ์˜ ์‹คํ–‰๋‹จ์œ„ 
Job์„ ๋งŒ๋“ค์ˆ˜์žˆ๋„๋ก JobBuilderFactoryํด๋ž˜์Šค๋ฅผ ์ œ๊ณต์„ ํ•˜๋Š”๋ฐ ์ด ํด๋ž˜์Šค๋Š” Spring Batch์„ค์ •์— ์˜ํ•ด์„œ ์ด๋ฏธ bean์œผ๋กœ ์ƒ์„ฑ๋˜์–ด์žˆ๊ธฐ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž ์ฃผ์ž…์œผ๋กœ ๋ฐ›์„์ˆ˜์žˆ๋‹ค. 
Job์€ ์‹คํ–‰๋‹จ์œ„๋ฅผ ๊ตฌ๋ถ„ํ• ์ˆ˜ ์žˆ๋Š” Incrementer์™€ Job์˜ ์ด๋ฆ„, step๋ฅผ ์„ค์ •ํ•œ๋‹ค. RunIdIncrementer๋Š” ์ƒˆ๋กœ์šด job์ธ์Šคํ„ด์Šค๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” Job์ด ์‹คํ–‰ํ• ๋•Œ๋งˆ๋‹ค ํ•ญ์ƒ ํŒŒ๋ผ๋ฏธํ„ฐ id๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ๋ฉฐ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†๋Š” batch๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๋ฉด ๋งค๋ฒˆ ์‹คํ–‰ํ• ๋•Œ๋งˆ๋‹ค ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. job์˜ ์ด๋ฆ„์€ spring batch๋ฅผ ์‹คํ–‰ํ•ด์ค„์ˆ˜ ์žˆ๋Š” key์ด๊ธฐ๋„ ํ•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  start ๋ฉ”์„œ๋“œ๋Š” job์‹คํ–‰์‹œ ์ตœ์ดˆ๋กœ ์‹คํ–‰๋  ์Šคํƒญ์„ ์„ค์ •ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค. 


Step์€ job์˜ ์‹คํ–‰๋‹จ์œ„์ธ๋ฐ ํ•˜๋‚˜์˜ job์€ ํ•œ๊ฐœ ์ด์ƒ์˜ step๋ฅผ ๊ฐ€์งˆ์ˆ˜ ์ž‡๋‹ค. step์€ tasklet์ด๋ผ๋Š” ๊ฐ์ฒด๋กœ ๋ฐฐ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. step๋„ job์ฒ˜๋Ÿผ ํ•˜๋‚˜์˜ bean์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๋ฐ job๊ณผ step์€ spring batch์—์„œ ๊ฑฐ์˜ ๋ชจ๋“ ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ์ˆ˜์žˆ๋‹ค. stepBuilderFactory๋„ ์ƒ์„ฑ์ž ์ฃผ์ž…์œผ๋กœ ๋ฐ›๋Š”๋‹ค. Step๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฆ„ ์„ค์ •์ด ํ•„์š”ํ•˜๊ณ  tasklet์ด๋ผ๋Š” step ์‹คํ–‰ ๋‹จ์œ„๋ฅผ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค. task๊ธฐ๋ฐ˜๊ณผ chunk๊ธฐ๋ฐ˜์ด ์žˆ๊ณ  ์ด๋ฒˆ์—๋Š” task๊ธฐ๋ฐ˜์œผ๋กœ ์„ค์ •ํ•ด๋ณธ๋‹ค. 

 

 

 

์Šคํ”„๋ง ๋ฐฐ์น˜ ์„ค์ •

 

  • spring-batch-core/org.springframework/batch/core/* ์— ์œ„์น˜
  • ์Šคํ”„๋ง ๋ฐฐ์น˜๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ…Œ์ด๋ธ”
  • schema.sql ์„ค์ •
    • schema-**.sql์˜ ์‹คํ–‰ ๊ตฌ๋ถ„์€ DB ์ข…๋ฅ˜๋ณ„๋กœ script๊ฐ€ ๊ตฌ๋ถ„
    • spring.batch.initialize-schema config๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
    • ALWAYS, EMBEDDED, NEVER๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
      • ALWAYS : ํ•ญ์ƒ ์‹คํ–‰
      • EMBEDDED : ๋‚ด์žฅ DB์ผ ๋•Œ๋งŒ ์‹คํ–‰
      • NEVER : ํ•ญ์ƒ ์‹คํ–‰ ์•ˆํ•จ
      • ๊ธฐ๋ณธ ๊ฐ’์€ EMBEDDED๋‹ค.

 

spring batch์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ job์„ ์‹คํ–‰ํ• ์ˆ˜์žˆ๋Š” ์„ค์ •๊ฐ’์„ ์ œ๊ณตํ•˜๋Š”๋ฐ ์ด ๊ฐ’์„ ์„ค์ •ํ•˜์ง€์•Š์œผ๋ฉด ๋ชจ๋“  batch๊ฐ€ ์‹คํ–‰๋˜๊ธฐ๋•Œ๋ฌธ์— application.yml ์—์„œ ์„ค์ •๊ฐ’์„ ์ถ”๊ฐ€ํ•œ๋‹ค.  

spring:
  batch:
    job:
      names: ${job.names:NONE}
    jdbc:
      initialize-schema: 

Edit Configuration์˜ program arguments ๋ถ€๋ถ„๋„ ์„ค์ •ํ•ด์ค€๋‹ค.