스프링 배치(Spring batch)란?

현주·2023년 6월 4일
1

✏️ 스프링 배치 ( Spring batch )

[ spring-batch docs ]

  • 대용량 일괄 처리의 편의를 위해 설계된 가볍고 포괄적인 배치 프레임워크

  • 배치 = 일괄처리
    ➜ 지정한 스케줄러에 의해 정해진 시간에 맞춰 작업 수행

  • 로깅/추적, 트랜잭션 관리, 작업 처리 통계, 작업 재시작, 건너뛰기, 리소스 관리 등 대용량 레코드 처리에 필수적인 기능을 제공

Ex. 우리 프로젝트( 카풀 서비스 )에서,
게시글에 작성한 카풀 출발 시간이 현재 시간을 지나면 게시글의 상태를 마감으로 변경하는 작업에서 스프링 배치를 사용하였다.

✔ 스케줄링 (Scheduling)

  • 정해진 일정 또는 주기에 따라 작업을 실행하는 기능
  • 주로 주기적으로 실행되는 반복 작업에 사용됨
  • 스프링 프레임워크에서는 @Scheduled 애너테이션을 사용하여 메서드에 스케줄링을 설정하며, 주기적으로 해당 메서드가 실행되도록 예약 가능
  • 주로 백그라운드 작업, 일정한 주기로 데이터를 처리하는 작업, 리소스 관리 등에 활용

💡 Batch VS Scheduler

  • Spring Batch
    ➜ Batch Job을 관리
    ➜ But, Job을 구동하거나 실행시키는 기능은 지원하고 있지 않음
  • Scheduler
    ➜ Spring에서 Batch Job을 실행시키기 위해 사용
    Ex. Quartz, Scheduler, Jenkin 등

    👉 Batch의 실행을 위해서는 Scheduler와 함께 사용해야 함 !
    Ex. Quartz + Batch

✔ 장점

  • 유지보수성
    ➜ 테스트 용이, 추상화, 풍부한 API
    ➜ 트랜잭션 및 커밋 횟수와 같은 것들을 애플리케이션에 제공하므로, 처리가 어디까지 진행됐는가라든가 실패시 무슨 일을 해야 하는지 관리할 필요 X

  • 유연성
    ➜ JVM을 이용한 이식성
    ➜ 시스템 간 코드 공유 능력 (POJO 재활용 등 )

  • 확장성
    ➜ 과거의 메인프레임 방식이나, 커스텀하게 처리하던 방식은 병렬 처리를 하려면 고려할게 많아 확장성과 안정성이 떨어지는데,
    스프링 배치는 단일 처리 / 병력 처리 등이 모두 가능

  • 개발 리소스, 지원
    ➜ 자바, 스프링 프레임워크를 기반
    ➜ 커뮤니티의 강력한 지원

  • 비용
    ➜ 오픈 소스임


✔ 스프링 배치 Application의 조건

  • 대용량 데이터
    ➜ 대용량의 데이터를 가져오거나 전달, 계산하는 등의 처리가 가능해야함

  • 자동화
    ➜ 하드웨어 적인 문제를 제외하고는 사용자의 개입이 없이 실행되어야 함

  • 견고성
    ➜ 잘못된 데이터를 충돌/중단 없이 처리할 수 있어야 함

  • 신뢰성
    ➜ 무엇이 잘못되었는지를 추적할 수 있어야 함 ( 로깅 / 알림 )

  • 성능
    ➜ 지정한 시간 안에 처리를 완료하거나 동시에 실행되는 다른 애플리에킹션을 방해하지 않도록 수행되어야 함


✔ 스프링 배치를 사용하는 경우 ( 일괄 처리가 필요한 경우 )

  • 대용량의 비즈니스 데이터를 복잡한 작업으로 처리해야하는 경우

  • 특정한 시점에 스케줄러를 통해 자동화된 작업이 필요한 경우

  • 대용량 데이터의 포맷을 변경, 유효성 검사 등의 작업을 트랜잭션 안에서 처리 후 기록해야하는 경우


✔ 스프링 배치 계층 구조

  • Application
    ➜ Spring Batch를 사용하여 개발자가 작성한 모든 배치 작업과 사용자 정의 코드

  • Batch Core
    ➜ 배치 작업을 시작하고 제어하는 데 필요한 핵심 런타임 클래스를 포함

  • Batch Infrastructure
    ➜ 개발자와 애플리케이션에서 사용하는 일반적인 Reader와 Writer, RetryTemplate과 같은 서비스를 포함

스프링 배치의 계층 구조가 위와 같이 설계되어 있기 때문에, 개발자 입장에서
👉 비즈니스 로직은 Application 계층에서 집중이 가능하고
👉 배치의 동작과 관련된 것은 Batch Core에 있는 클래스들을 이용하여 제어 가능


✔ 스프링 배치 아키텍처

  • Job

    • 배치 처리 과정을 하나의 단위로 만들어 놓은 객체
    • 배치 처리 과정에 있어 전체 계층 최상단에 위치
    • 최소한 1개 이상의 Step을 가져야 함
  • JobInstance

    • Job의 실행의 단위 ( Job.execute를 호출하는 역할 )
    • Job을 실행시키게 되면 하나의 JobInstance가 생성

      Ex.
      1월 1일 실행, 1월 2일 실행을 하게 되면 각각의 JobInstance가 생성되며
      1월 1일 실행한 JobInstance가 실패하여 다시 실행을 시키더라도 이 JobInstance는 1월 1일에 대한 데이터만 처리

    • Job의 재실행 가능 여부 검증, 잡의 실행 방법, 파라미터 유효성 검증 등을 수행
  • JobParameters

    • 배치 작업이 수행될때 마다 전달되는 Parameter

      Ex. 시작 시간, 데이터를 읽을 범위 등을 지정하여 Batch Job Instance를 생성한다면, 이 때 넘어가는 인자가 JobParameter

    • JobInstance를 구별할 때 사용
    • String, Double, Long, Date 4가지 형식 지원
  • JobExecution

    • JobInstance의 실행 시도에 대한 객체
    • 실패하여 재실행 시킨 경우 2번 실행에 대한 JobExecution은 개별로 생기게 됨
      ( 동일한 JobInstance )
    • JobInstance 실행에 대한 상태, 시작시간, 종료시간, 생성시간 등의 정보를 담음
  • Step

    • Job을 구성하는 독립된 작업의 단위
    • 순차적인 단계를 캡슐화함
    • Job의 실제 일괄 처리를 제어하는 모든 정보를 포함함
    • Tasklet, Chunk의 2가지 기반이 존재
  • StepExecution

    • Step 실행 시도에 대한 객체
    • Step이 실제로 시작될 때만 생성됨

      Ex. Job이 여러개의 Step으로 구성되어 있을 경우,
      이전 단계의 Step이 실패하면 이후 StepExecution은 생성되지 않음

    • JobExecution에 저장되는 정보 외에 read 수, write 수, commit 수, skip 수 등의 정보들도 저장됨
  • ExecutionContext

    • Job에서 데이터를 공유 할 수 있는 데이터 저장소
    • Spring Batch에서 제공하는 ExecutionContext는 JobExecutionContext, StepExecutionContext의 2가지 종류
      But, 이 두가지는 지정되는 범위가 다름
      • JobExecutionContext - Commit 시점에 저장
      • StepExecutionContext - 실행 사이에 저장
    • ExecutionContext를 통해 Step간 Data 공유 가능
    • Job 실패시 ExecutionContext를 통한 마지막 실행 값을 재구성 가능
  • JobRepository

    • 위의 모든 배치 처리 정보를 담고있는 매커니즘
    • 일반적으로 관계형 데이터베이스를 사용하며 스프링 배치 내의 대부분의 주요 컴포넌트가 공유
    • Job이 실행되면 JobRepository에 JobExecution과 StepExecution을 생성하고,
      JobRepository에서 Execution 정보들을 저장하고 조회하며 사용하게 됨
  • JobLauncher

    • Job과 JobParameters를 사용하여 Job을 실행하는 객체
    • Job.execute을 호출하는 역할
  • ItemReader

    • Step(Database)에서 배치 처리할 Item을 읽어오는 역할
    • ItemReader에 대한 다양한 인터페이스가 존재하고, 다양한 방법으로 Item을 읽어올 수 있음
  • ItemProcessor

    • Reader로 읽어온 Item을 데이터를 가공/처리하는 역할
    • 배치를 처리하는데 필수 요소는 아님
    • item을 필터 도중 null로 리턴하면, 그 item은 write로 전달되지 못함
      ( 값이 정확히 있는 item들만 write로 전달됨 )
  • ItemWriter

    • Processor로 가공/처리 된 데이터들(items : List< item >)을 Database에 저장하는 역할
    • 처리 결과물에 따라 Insert / Update / Queue를 사용한다면 Send가 될 수도 있음
    • ItemWriter에 대한 다양한 인터페이스가 존재
    • 기본적으로 item들은 List 단위로 처리되며, 그 List는 Chunk 단위로 처리됨

[참고] https://12bme.tistory.com/646
[참고] https://dejavuhyo.github.io/posts/spring-batch/


✔ Spring batch의 메타 데이터


Spring batch는 Job의 수행 결과를 저장하기 위해 메타 데이터를 DB에 반드시 저장하는데,

Ex.
이전에 실패한 Job들이 어떤 것들이 있는지,
최근에 실패한 Batch Parameter가 어떤 것들이 있고, 성공한 Job들은 어떤 것들이 있는지,
다시 실행한다면 어디서부터 시작하면 될지,
어떤 Job에 어떤 Step들이 있었고, Step들 중 성공한 Step과 실패한 Step들은 어떤 것들이 있는지 등

이를 통해 과거, 현재의 실행에 대한 여러 정보와 성공/실패 여부 등을 관리하여
배치 운용에 있어 리스크 발생 시에 빠르게 대처가 가능하다.

Spring batch에서 제공하는 메타 데이터 스키마는 위와 같이 총 6개의 테이블로 이루어져 있고,

위 ERD 관계를 보면,
1. BATCH_JOB_INSTANCE
2. BATCH_JOB_EXECUTION
3. BATCH_JOB_EXECUTION_PARAM
4. BATCH_JOB_EXECUTION_CONTEXT
5. BATCH_STEP_EXECUTION
6. BATCH_STEP_EXECUTIOIN_CONTEXT
의 순서로 데이터가 적재될 것이다.

✔️ 메타 데이터 테이블 살펴보기

< Job 관련 테이블 >

  • BATCH_JOB_INSTANCE
    ➜ Job이 실행될 때 JobInstance 정보가 저장되며 job_name과 job_key를 키로 하여 하나의 데이터가 저장됨
    ➜ 동일한 job_name과 job_key로 중복 저장될 수 없음
  • BATCH_JOB_EXECUTION
    ➜ Job의 실행정보가 저장
    ➜ Job 생성, 시간, 종료 시간, 실행상태, 메시지 등을 관리
  • BATCH_JOB_EXECUTION_PARAMS
    ➜ Job과 함께 실행되는 JobParameter 정보를 저장
  • BATCH_JOB_EXECUTION_CONTEXT
    ➜ Job의 실행동안 여러가지 상태정보, 공유 데이터를 직렬화(Json 형식)해서 저장
    ➜ Step 간 서로 공유 가능

< Step 관련 테이블 >

  • BATCH_STEP_EXECUTION
    ➜ Step의 실행정보가 저장
    ➜ 생성, 시작, 종료 시간, 실행상태, 메시지 등을 관리
  • BATCH_STEP_EXECUTION_CONTEXT
    ➜ Step의 실행동안 여러가지 상태정보, 공유 데이터를 직렬화(Json 형식) 해서 저장
    ➜ Step별로 저장되며 Step간 서로 공유 불가능

[ spring-batch/docs 참고 ]
[ spring batch 메타데이터 테이블 요소 참고 ]

✔️ 메타데이터(Metadata)

  • 데이터에 관한 구조회된 데이터
  • 다른 데이터를 설명해주는 데이터
  • 대량의 정보 가운데에서 찾고있는 정보를 효율적으로 찾아내 이용하기 위해 일정한 규칙에 따라 콘텐츠에 대해 부여되는 데이터
    [ wikipeia 메타데이터 ]

✔️ DDL 스크립트

메타 데이터 테이블의 DDL은 /org/springframework/batch/core/ 패키지 하위에
schema-*.sql형식으로 DB 유형별 기본 DB 스키마가 제공되고,

Spring batch는 기본적으로 Boot가 실행될 때 자동으로 메타 데이터를 위와 같이 생성해준다.

But, Spring batch에서 공식적으로 지원하지 않는 DB를 연동하여 사용할 경우,
DB 스키마가 자동으로 생성이 되지 않아 정보를 저장할 곳이 없어 Spring Batch 실행 과정에서 Exception이 발생하는데,

이 경우, build.gradle에 추가했던 Spring Batch 라이브러리의
org.springframework.batch.core -shema-mysql.sql 파일에 작성된 SQL을 그대로 실행하면 메타 테이블을 생성할 수 있고,

생성 후 애플리케이션을 다시 실행해주면 Job이 제대로 작동하는 것을 알 수 있다.

또는 아래와 같이 application.yml에 DB 스키마 생성 전략을 설정하여 DB 스키마의 생성이 가능하다!

✔️ 생성 전략

  • always
    ➜ DB 스키마 생성 SQL을 항상 실행
    ➜ RDBMS 설정이 되어 있을 경우, 내장 DB보다 우선적으로 실행됨
  • embedded (default)
    ➜ 내장 DB의 경우만 실행되고, 스키마가 자동으로 생성됨
  • never
    ➜ DB 스키마 생성 SQL 항상 실행하지 않음
    ➜ 내장 DB인 경우, 스크립트가 생성되지 않기 때문에 오류 발생
    ➜ 운영에서 수동으로 스크립트 생성 후 설정 권장

위 생성 전략을 활용하여 DB 스키마를 생성하면, Spring batch를 위한 테이블이 아래와 같이 9개가 만들어진다.

[참고] https://ojt90902.tistory.com/762


📌 다음 포스팅은 Tascklet / Chunk에 대한 내용입니다.

👉 Tasklet vs Chunk 비교와 처리 테스트

0개의 댓글