나 JAVA 봐라

Spring Batch - 개념 본문

Spring/Spring Batch

Spring Batch - 개념

cool_code 2024. 1. 2. 21:17

이전 프로젝트에서 API 호출해서 데이터를 가져올 때 스케줄러만 사용하여서 주기적으로 해당 작업이 반복되도록 했었다. 이번 프로젝트에서는 API 호출 시 가져오는 데이터를 스프링 배치를 통해 처리해보려 한다.

 

이제 Spring Initializer에서 Spring Boot 2점대 버전이 지원되지 않아서, 3.1.6 버전을 사용하여 프로젝트를 진행하고 있다.

이에 따라 3버전 부터는 Spring Batch 5버전을 사용하도록 업데이트가 되어서, 레퍼런스가 많지 않은 Batch 5 버전을 사용해야 한다.

배치에 대한 어느정도의 개념이 있어야 바뀐 점이 많은 5 버전을 잘 사용할 수 있을 것 같아, 기본적인 개념을 먼저 공부해보았다. 


스프링 배치 그게 뭔데 어떻게 하는건데

  • 스프링 배치 : 대용량 데이터를 처리하기 위한 프레임 워크
  • 대량의 데이터 처리하거나, 주기적이고 반복적인 작업을 실행하는데 사용한다.
  • 제공하는 기능들
    • 로깅 및 추적
    • 트랜잭션 관리
    • 작업 처리 통계
    • 작업 재시작
    • 건너뛰기
    • 리소스 관리

아래에서 스프링 배치에 사용되는 용어들과 각각의 역할에 대해 이해하게 된다면 왜 위의 기능들이 제공되는지 이해할 수 있을 듯 하다. 

 

Batch와 Scheduler

저번 프로젝트 때 원래 배치를 사용하려다가 굳이 대용량도 아닌데 왜 배치를 사용하냐는 피드백을 받고, 스케줄러를 사용했었다.

생각해보니 배치와 스케줄러를 혼동해서 이해하고 있어서, 다시 차이에 대해 짚고 넘어가보려고 한다. 

 

배치: 대량의 데이터를 '일괄'적으로 처리

스케줄러: 일정 주기마다 실행

 

즉, 배치는 특정 주기마다 자동으로 돌아가는 것(= 스케줄링)과 관련이 없다.

Spring Batch는 이런 대용량 데이터를 처리할 때 스케줄러를 함께 쓸 수 있도록 되어 있는 프레임 워크인 것이다. 그리고 이런 작업 스케줄링을 위해 Quartz, Scheduler 등의 스케줄러를 사용한다. 

즉 Spring Batch 자체에서는 Batch Job은 관리하지만 Job을 구동, 실행시키는 것은 스케줄러를 통해 할 수 있다. 

 

Spring Batch 용어

Job

  • 배치처리 과정을 하나의 단위로 만들어 놓은 객체
  • 배치처리 과정 시 전체 계층 최상단에 위치한다.

JobInstance

  • Job의 실행 단위
  • Job 한 번 실행할 때 마다 하나씩 생성함. 
  • 예를 들어 Job이 하루에 한 번씩 실행될 때, 각각의 실행 일자마다 JobInstance 하나씩 생성된다. 1월 1일에 실행되면 1월 1일 JobInstance, 1월 2일 생성되면 1월 2일 JobInstance 가 생성되는 것이다. 만약 1월 1일에 실행한 JobInstance가 실패하여 재실행 시켜도 JobInstance는 1월 1일에 대한 데이터만 처리한다.

JobParameters

  • JobInstance를 구별하기 위한 객체
  • JobInstance에 전달되는 매개변수
  • String, Double, Long, Data 4가지 형식을 지원한다.
  • 중복 실행 막기 위해 성공 이력 있는 Batch는 동일한 파라미터로 실행할 때 Exception이 발생한다.

JobExecution

  • JobInstance 실행 시도에 대한 객체
  • 예를 들어 1월 1일 JobInstance가 실패해서 재실행할 경우, 동일한 JobInstance를 실행하지만 2번의 실행에 대해 JobExecution은 각각 생긴다. 즉 2개가 생긴다.
  • JobInstance 실행에 대한 상태, 시작시간, 종료시간, 생성시간 등의 정보를 담고 있다. 

Step

  • Job의 하위단계로, 실제 배치 처리 작업이 이뤄진다.
  • Job은 최소한 1개 이상의 Step을 갖고, 순차적으로 Step이 처리된다.
  • Step은 chunk 방식 혹은 Tasklet 방식으로 생성할 수 있다. 

StepExecution

  • Step 실행 시도에 대한 객체 (JobExecution과 동일하다.)
  • Job이 여러 개의 Step으로 구성되어 있을 경우, 이전 단계의 Step이 실패하면 다음 단계의 Step이 실행되지 않으므로 실패 이후의 StepExecution은 생성되지 않는다. (즉, 각 Step의 실행 시도마다 새로운 StepExecution이 생성된다.)
  • read(읽은 아이템 수) , write(쓴 아이템 수), commit(커밋 횟수), skip(스킵한 아이템 수) 등의 Step 실행 정보가 저장된다.

 

ExecutionContext

  • Step 혹은 Job 실행 도중 데이터를 공유하기 위해 사용되는 저장소
  • JobExecutionContext, StepExecutionContext 두 종류가 있다.
  • Job 혹은 Step이 실패했을 경우, ExecutionContext를 통해 마지막 실행 상태를 재구성하여 재시도, 복구 작업 등을 수행할 수 있다.

JobRepository

  • 배치 작업에 관련된 모든 정보를 저장, 관리하는 메커니즘
  • JobExecution, StepExecution, JobParameter 등을 저장, 관리한다.
  • Job이 실행될 때 JobRepository는 새로운 JobExecution과 StepExecution을 생성하고, 이를 통해 실행 상태를 추적한다. 

JobLauncher

  • Job, JobParameters를 받아 Job을 실행한다.
  • 전반적인 Job의 생명 주기를 관리하며, JobRepository를 통해 실행 상태를 유지한다.

나중에 스케줄링을 한다면, JobLauncher을 불러와서 스케줄링 처리를 할 듯 하다.

 

ItemReader

  • 배치 작업에서 처리할 아이템을 읽어온다.
  • 여러 형식의 데이터 소스(DB, 파일, 메시지 큐 등)로 부터 데이터를 읽어오는 다양한 ItemReader 구현체가 제공된다.

API를 통해 데이터를 JSON 형태로 가져오는 것을 ItemReader에서 하는 것이 맞는지 궁금해진다.


ItemProcessor

  • ItemReader로부터 읽어온 아이템을 처리하는 역할
  • 필요에 따라 사용하며, 데이터 필터링, 변환 등의 작업을 수행한다.

ItemWriter

  • ItemProcessor에서 처리된 데이터를 최종적으로 기록하는 역할
  • 다양한 형태의 구현체를 통해 데이터베이스에 기록하거나, 파일을 생성하거나 메시지를 발행하는 등 다양한 방식으로 데이터를 쓴다.


Tasklet

  • 간단한 단일 작업, 예를 들어 리소스의 정리 또는 시스템 상태의 체크 등을 수행할 때 사용
  • 스프링 배치의 Step 내에서 단일 작업을 수행하기 위한 인터페이스로, 일반적으로 ItemReader, ItemProcessor, ItemWriter의 묶음을 가지는 Chunk 기반 처리 방식과 다르다.
  • Tasklet의 execute 메서드는 Step의 모든 처리가 끝날 때까지 계속 호출된다.

목적이 대용량 데이터 처리라면 Chunk를 사용해야 Spring Batch를 사용하는 의미가 있을 것 같음.


JobOperator

  • Job의 실행과 중지, 재시작 등의 배치 작업 흐름제어를 담당한다.
  • JobLauncher와 JobRepository에 대한 직접적인 접근 없이도 배치 작업을 수행하고 상태를 조회할 수 있다.


JobExplorer

  • Job의 실행 이력을 조회하는 데 사용된다.
  • JobRepository에서 제공하는 정보와 유사하지만, JobRepository는 주로 Job의 실행 도중인 상태에 대해 업데이트하고 관리하는 반면, JobExplorer는 주로 읽기 전용 접근에 초점을 맞추고 있다. 

그리고 만약 배치를 돌리다가 장애가 난다면 어떻게 처리할 수 있을까? (ex. 외부 API 호출하여 DB 업데이트하는 배치 작업 중 외부 API 먹통이거나,,,... 등)

아래와 같이 지정할 수 있다고 한다. 

  • skip : 특정 오류 지정하여 지정한 횟수만큼 발생 무시
  • retry : 특정 오류 지정하여 지정 횟수만큼 재시도

 

-> 한 줄로 요약하자면, Spring Batch는 대용량 데이터를 일괄적으로 처리하기 위한 설계도, 순서도와 같은 느낌인 것 같다. 실제 구현은 순서도에 적혀있는 각 단계(ex. reader, writer,...) 에 코드 구현하면 실행할 때 Batch가 순서에 맞게 작성한 코드를 수행한다. (Batch도 대용량 데이터의 개념)

 

실제로 위의 객체들이 DB 테이블로 어떻게 꽂히는지에 대한 내용은

https://jojoldu.tistory.com/326

을 참고하면 좋을 듯 하다 !

 


참고

https://godekdls.github.io/Spring%20Batch/domainlanguage/

https://khj93.tistory.com/entry/Spring-Batch%EB%9E%80-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B3%A0-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

https://yeonyeon.tistory.com/310