JaeWon's Devlog
article thumbnail
Published 2022. 8. 26. 13:26
[Spring] Spring Batch 정리 BackEnd/Spring
반응형

회사에서 업무를 하나씩 배우고 맡게 되면서, Spring Batch 를 사용하고 있는 배치서버를 맡게 되었습니다.

이전 스케줄링 관련 개발을 할 때는 Crontab, Quartz 등을 사용하였는데, 여기서는 Spring Batch 를 사용하고 있었고, 해당 내용을 이해하는데 러닝커브도 있어 정리하고자 합니다.

추후에는 Spring Batch 사용 예제에 대해서도 포스팅할 예정입니다.


1. Spring Batch

- Spring Batch 는 일괄 처리를 위한 오픈 소스 프레임워크이다.

Batch Processing(일괄 처리)
사용자의 개입 없이 실행을 스케줄링할 수 있는 작업(job)을 의미하며. 컴퓨터 프로그램 흐름에 따라 순차적으로 자료를 처리하는 방식이다. 배치는 예약된 시간에 자동으로 실행될 수 있으며 컴퓨터 리소스의 가용성에 따라 실행될 수도 있다.

- Spring Framework 의 POJO 기반 개발 접근 방식을 기반으로 동작한다.

- 배치 프로세싱을 기반으로 로깅/추적, 트랜잭션 관리, 작업 처리 통계, 작업 재시작, 건너뛰기, 리소스 관리 등 대용량 레코드 처리에 필수적인 기능을 제공한다.

- 최적화 및 파티셔닝 기술을 통해 대용량 및 고성능 배치 작업을 가능하게 한다.

- 배치가 실패하여 작업 재시작을 하게 되면 처음부터가 아닌 실패한 지점부터 재실행을 하게 된다.

- 중복 실행을 막기 위해 성공한 이력이 있는 Batch 는 동일한 Parameters 로 실행 시 Exception 이 발생하면서 중복 실행이 되지 않는다.

1-1. Spring Batch VS Quartz, Scheduler ?

https://loosie.tistory.com/838

Spring Batch 는 Scheduler 가 아니기 때문에 비교 대상은 아니다.

- Spring Batch는 Batch Job 을 관리하지만, 실질적으로 이 Job을 구동하거나 실행시키는 기능은 지원하지 않는다.

- Spring 에서 해당 Batch Job 을 실행시키기 위해서는, Quartz, Scheduler 등 전용 Scheduler 를 사용해야 한다.

 

[Spring] @Scheduled 어노테이션에서 cron 사용 및 정리

회사에서 업무를 할당받게 되면서 Spring Batch 를 사용하고 있는 배치서버를 맞게 되었습니다.(Spring Batch 에 대해서는 추후 포스팅하기위해, 공부하고 정리하고 있습니다...) 그전에 간단하게 스프

dev-jwblog.tistory.com

2. 스프링 배치 아키텍처와 구성 요소

2-1. 스프링 배치 구조

- 조금 더 쉽게 이해하기 위해 controller, service, dao 3-tier를 빗대어 생각해보았습니다.(주관적입니다!!!)

  • Run Tier
    - Application 의 Scheduling.
    - 실행을 담당.
    - Spring Batch 는 따로 Scheduling 기능을 제공하지 않고, Quartz 나 Cron 을 이용하도록 권고.
  • Job Tier
    - 전체적인 Job 의 수행을 책임.
    - Job 내의 각 Step 을 정책에 따라 순차적으로 수행.
    - 3-tier 중 Controller(요청을 전달받아 Job 호출).
  • Applictaion Tier
    - Job 을 수행하는데 필요한 Component.
    - 3-tier 중 Service(Job을 실행하여 요청 처리).
  • Data Tier
    - Database, Queue 등 물리적 데이터 소스.
    - 3-tier 중 Dao(Job 실행 중 데이터 관련 처리).

2-2. 스프링 배치 구성요소

  • JobLauncher
    - JobLauncher 는 배치 Job 을 실행시키는 역할.
    - Job 과 JobParameter 를 받아 실행하고, JobExcution 을 반환.
public interface JobLauncher {
    public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException;
}
  • Job
    - 실행하고자 하는 작업.
    - 논리적인 Job 실행의 개념.
    - Job Configuration 과 대용되는 단위.
public interface Job {
    String getName(); 				// 작업의 이름
    boolean isRestartable(); 			// 재시작 가능여부
    void execute(JobExecution execution); 	// 작업을 실행
}
  • Step
    - Batch Job 을 구성하는 독립적인 하나의 단계.
    - Job 은 하나 이상의 Step 으로 구성.
  • JobRepository
    - 수행되는 Job에 대한 정보를 담고 있는 저장소.
    - 특정 Job 에 대한 수행 시간, 횟수, 결과 등 Batch 수행과 관련된 meta data 가 저장.

3. Spring Batch 용어

  • Job
    - 배치처리 과정을 하나의 단위로 만들어 놓은 객체.
    - 전체 배치 프로세스를 캡슐화하는 엔티티, 실행시킬 작업.
  • JobInstance
    - 논리적인 Job 의 실행의 단위.
    - Job 을 실행시키면 하나의 JobInstance 가 생성.
    - 예를들어, 1월 1일 실행, 1월 2일 실행을 하게 되면 각각의 JobInstance 가 생성되고, 만약 1월 1일에 실행한 JobInstance 가 실패하여 이후 재실행 하더라도 이 JobInstance 는 1월 1일에 대한 데이터만 처리.
  • JobParameters
    - Job 을 실행하는데 사용하는 파라미터의 집합으로.
    - Job 이 실행되는 동안에 JobInstance 의 식별 외에도 매개변수 역할로 사용.
    - String, Double, Long, Date 4가지 형식만 지원.
  • JobExecution
    - JobInstance 에서 실행 시도에 대한 객체.
    - 실행에 대한 JobExecution 은 개별로 생성.
    - JobInstance 실행에 대한 상태, 시작시간, 종료시간, 생성시간 등의 정보를 가짐.
    - 예를들어, 1월 1일에 실행한 JobInstance 가 실패하여 재실행을 하여도 동일한 JobInstance 를 실행시키지만 이 2번에 실행에 대한 Job Execution 은 개별로 생성.
  • Step
    - Job 의 배치처리를 정의하고 순차적인 단계를 캡슐화.
    - Job 은 최소 1개 이상의 Step 을 가져야 하고, Job 의 실제 일괄 처리를 제어하는 모든 정보를 포함.
    - Step 의 내용은 개발자의 선택에 따라 구성.
    - Tasklet 처리 방식과 Chunk 지향 처리 방식을 지원
    • Tasklet
      - 단순한 데이터 프로세스 처리에 적합한 모델.
      - SQL 1회 명령 등 단순하거나, 작업 프로세스의 표준화가 어려운 복잡한 경우에 Custom 작업 생성을 위해 사용.
    • Chunk
      - 메모리에 가지고 있기 너무 많고, 큰 데이터 들을 효율적으로 처리하는데 적합.
      - 일정양의 데이터를 일괄적으로 read / process / write 프로세스 흐름에 따라 표준화하여 작업을 구현.
      - 하나의 Transaction 안에서 처리할 Item 의 덩어리.
      - chunk size 가 10이라면 하나의 transaction 안에서 10개의 item 에 대해 처리 하고 commit.
  • StepExecution
    - JobExceution 과 동일하게 Step 실행 시도에 대한 객체.
    - 실제 시작이 될 때 생성.
    - 시작 시간, 종료 시간, 상태, 종료 상태, Commit Count, ItemCount, Skip Count 등 실행에 대한 다양한 정보를 가짐.
    - 만약 Job 이 여러 단계의 Step 으로 구성되어 있을 경우 이전 단계의 Step 이 실패하게 되면 다음 단계가 실행되지 않음으로 실패 이후 StepExecution 은 생성되지 않음.
  • ExecutionContext
    - Job 에서 데이터를 공유 할 수 있는 데이터 저장소.
    - Spring Batch 에서는 JobExecutionContext, StepExecutionContext 를 지원.
    • JobExecutionContext
      - Commit 시점에 저장
    • StepExecutionContext
      - 실행 사이에 저장
    • ExecutionContext 를 통해 Step 간 Data 공유가 가능하고, Job 실패시 ExecutionContext 를 통해 마지막 실행 값을 재구성 할 수 있음.
  • JobRepository
    - 수행되는 Job 의 모든 정보를 담고 있는 저장소.
    - 어떠한 Job 이 언제 수행되었고, 언제 종료하고, 몇 번 실행되었고, 실행에 대한 결과가 어떤지 등의 Batch 수행과 과련된 모든 Meta Data 가 저장.
    - Job 이 실행되게 되면 JobRepository 에 JobExecution 과 StepExecution 을 생성하고, JobRepository 에서 Execution 정보들을 저장하고 조회하며 사용.
  • Item
    - 처리할 데이터의 가장 작은 구성 요소.
    - 예를들면, 파일의 한줄, DB의 한 Row, XML 의 특정 element.

https://loosie.tistory.com/838

  • ItemReader
    - Step 에서 Item 을 읽어오는 인터페이스.
    - 다양한 인터페이스가 존재하여 다양한 방법으로 Item 을 읽음.
    - DB 데이터뿐만 아니라, File, XML, JSON, CSV 등 읽어 올 수 있음.
  • ItemWriter
    - 처리된 Data 를 Writer 할 때 사용.
    - Write 는 처리 결과에 따라 Insert, Update, Send 등 알맞게 사용.
    - 최신 버전의 Spring Batch 에서는 Item 을 Chunk 단위로 묶어 처리.
  • ItemProcessor
    - Reader 에서 읽은 Item 데이터를 처리.
    - 배치를 처리하는데 필수 요소는 아니지만, 역할을 명확하게 구분하기 위해 사용.

4. Meta-Table Schema

- Spring Batch 에서는 6개의 Meta Table 과 3개의 Sequence Table 이 존재합니다.

- 작업이 수행될 때 마다 실행된 Job 에 대한 다양한 정보들을 저장하여 관리합니다.

- 일반적으로는 Meta Table 이 없으면 Spring Batch 를 실행할 수 없으나, 커스텀마이징을 통해 없이 수행 가능합니다.

  • Sequence Table
    - BATCH_JOB_SEQ
    - BATCH_JOB_EXECUTION_SEQ
    - BATCH_STEP_EXECUTION_SEQ
  • Meta Table
    - BATCH_JOB_INSTANCE
    - BATCH_JOB_EXECUTION
    - BATCH_JOB_EXECUTION_PARAMS
    - BATCH_JOB_EXECUTION_CONTEXT
    - BATCH_STEP_EXECUTION
    - BATCH_STEP_EXECUTION_CONTEXT

4-1. SEQUENCE

- BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_STEP_EXECUTION 의 Primary Key 는 시퀀스에 의해 생성됩니다.

- 아래 쿼리는 시퀀스를 생성하는 Create 쿼리 입니다.

CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
CREATE SEQUENCE BATCH_JOB_SEQ;

- MySQL 과 같은 DB 에서 시퀀스를 지원하지 않을 수 있어, 아래와 같은 쿼리를 통해 사용할 수 있습니다.

CREATE TABLE BATCH_STEP_EXECUTION_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_STEP_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_SEQ values(0);

4-2. META TABLE

  • BATCH_JOB_INSTANCE

- Job 이 실행될 때 생성되는 JobInstance 에 관한 정보를 저장.

- 전체 계층 구조의 최상위 역할.

CREATE TABLE BATCH_JOB_INSTANCE  (
  JOB_INSTANCE_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT,
  JOB_NAME VARCHAR(100) NOT NULL ,
  JOB_KEY VARCHAR(2500)
);
JOB_INSTANCE_ID  Primary Key
VERSION  해당 Row 가 Update 될 때마다 1 증가
JOB_NAME  jobBuilderFactory.get 에 설정한 Batch Job Name
JOB_KEY  동일한 작업에 대한 식별하는 키 값
  • BATCH_JOB_EXECUTION_PARAMS

- Job 을 실행 시킬 때 사용했던 JobParameters 에 대한 정보를 저장.
- String, Date, Long, Double 타입의 데이터만 저장 가능.

CREATE TABLE BATCH_JOB_EXECUTION_PARAMS  (
	JOB_EXECUTION_ID BIGINT NOT NULL ,
	TYPE_CD VARCHAR(6) NOT NULL ,
	KEY_NAME VARCHAR(100) NOT NULL ,
	STRING_VAL VARCHAR(250) ,
	DATE_VAL DATETIME DEFAULT NULL ,
	LONG_VAL BIGINT ,
	DOUBLE_VAL DOUBLE PRECISION ,
	IDENTIFYING CHAR(1) NOT NULL ,
	constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
	references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
);
JOB_EXECUTION_ID  BATCH_JOB_EXECUTION 테이블에 대한 외래키(Foeign Key)
TYPE_CD  저장된 값의 데이터 유형, NOT NULL
KEY_NAME  저장된 값의 이름, NOT NULL
STRING_VAL String 타입 값
DATE_VAL Date 타입 값
LONG_VAL Long 타입 값
DOUBLE_VAL Double 타입 값
IDENTIFYING 매개변수가 관련 ID 에 기여했는지 여부를 나타내는 플래그
  • BATCH_JOB_EXECUTION

- JobExecution 에 관련된 모든 정보를 저장.

- JobInstance 가 실행될 때 마다 시작시간, 종료시간, 종료 코드 등을 가짐.

CREATE TABLE BATCH_JOB_EXECUTION  (
  JOB_EXECUTION_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT,
  JOB_INSTANCE_ID BIGINT NOT NULL,
  CREATE_TIME TIMESTAMP NOT NULL,
  START_TIME TIMESTAMP DEFAULT NULL,
  END_TIME TIMESTAMP DEFAULT NULL,
  STATUS VARCHAR(10),
  EXIT_CODE VARCHAR(20),
  EXIT_MESSAGE VARCHAR(2500),
  LAST_UPDATED TIMESTAMP,
  JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
  constraint JOB_INSTANCE_EXECUTION_FK foreign key (JOB_INSTANCE_ID)
  references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ;
JOB_EXECUTION_ID  Primary Key
VERSION  해당 Row 가 Update 될 때마다 1 증가
JOB_INSTANCE_ID  BATCH_JOB_INSTANCE 테이블의 Foreign Key
CREATE_TIME  실행이 생성된 타임스탬프
START_TIME  실행이 시작된 타임스탬프
END_TIME  성공, 실패 상관 없이 실행이 완료된 타임스탬프
 이 컬럼이 빈 값이라면 어떤 유형의 오류가 있었고, 프레임워크가 실패하기 전 마지막   저장을 수행할 수 없었음을 나타냄
STATUS  실행 상태
EXIT_CODE  실행 종료 코드
EXIT_MESSAGE  작업이 종료에 대한 메시지
LAST_UPDATE  실행이 지속된 마지막 타임스탬프
  • BATCH_STEP_EXECUTION

- StepExecution 에 대한 정보를 저장.

- STEP_EXECUTION 정보인 읽은 수, 커밋 수, 스킵 수 등 다양한 정보를 추가로 보관.

CREATE TABLE BATCH_STEP_EXECUTION  (
  STEP_EXECUTION_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT NOT NULL,
  STEP_NAME VARCHAR(100) NOT NULL,
  JOB_EXECUTION_ID BIGINT NOT NULL,
  START_TIME TIMESTAMP NOT NULL ,
  END_TIME TIMESTAMP DEFAULT NULL,
  STATUS VARCHAR(10),
  COMMIT_COUNT BIGINT ,
  READ_COUNT BIGINT ,
  FILTER_COUNT BIGINT ,
  WRITE_COUNT BIGINT ,
  READ_SKIP_COUNT BIGINT ,
  WRITE_SKIP_COUNT BIGINT ,
  PROCESS_SKIP_COUNT BIGINT ,
  ROLLBACK_COUNT BIGINT ,
  EXIT_CODE VARCHAR(20) ,
  EXIT_MESSAGE VARCHAR(2500) ,
  LAST_UPDATED TIMESTAMP,
  constraint JOB_EXECUTION_STEP_FK foreign key (JOB_EXECUTION_ID)
  references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;
STEP_EXECUTION_ID  Primary Key
VERSION  해당 Row 가 Update 될 때마다 1 증가
STEP_NAME  stepBuilderFactory.get 에 설정한 Step Name
JOB_EXECUTION_ID  BATCH_JOB_EXECTUION 테이블의 Foreign Key
START_TIME  실행이 사작된 타임스탬프
END_TIME  성공, 실패 상관 없이 실행이 완료된 타임스탬프
 이 컬럼이 빈 값이라면 어떤 유형의 오류가 있었고, 프레임워크가 실패하기 전 마지막   저장을 수행할 수 없었음을 나타냄
STATUS  실행 상태
COMMIT_COUNT  실행 중에 단계가 트랜잭션을 커밋한 횟수
READ_COUNT  실행 중에 읽은 항목 수
FILTER_COUNT  실행 중에 필터링 된 항목 수
WRITE_COUNT  실행 중에 작성 된 커밋된 항목 수
READ_SKIP_COUNT  실행 중에 읽기에서 건너뛴 항목 수
WRITE_SKIP_COUNT  실행 중에 쓰기에서 건너뛴 항목 수
PROCESS_SKIP_COUNT  실행 중에 처리에서 건너뛴 항목 수
ROLLBACK_COUNT  실행 중에 롤백 된 항목 수
EXIT_CODE  실행 종료 코드
EXIT_MESSAGE  작업이 종료에 대한 메시지
LAST_UPDATE  실행이 지속된 마지막 타임스탬프
  • BATCH_JOB_EXECUTION_CONTEXT

- JobExecution 의 ExecutionContext 정보가 보관.

- ExecutionContext 데이터는 일반적으로 JobInstance 가 실패 시 중단된 위치에서 재시작 할 수 있는 정보를 저장.

CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT  (
  JOB_EXECUTION_ID BIGINT PRIMARY KEY,
  SHORT_CONTEXT VARCHAR(2500) NOT NULL,
  SERIALIZED_CONTEXT CLOB,
  constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
  references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;
JOB_EXECUTION_ID  BATCH_JOB_EXECUTION 테이블에 대한 Foreign Key
SHORT_CONTEXT  SERIALIZED_CONTEXT
SERIALIZED_CONTEXT  직렬화 된 Execution Context
  • BATCH_STEP_EXECUTION_CONTEXT

- StepExecution 의 ExecutionContext 정보가 보관.

- ExecutionContext 데이터는 일반적으로 JobInstance 가 실패 시 중단된 위치에서 재시작 할 수 있는 정보를 저장.

CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT  (
  STEP_EXECUTION_ID BIGINT PRIMARY KEY,
  SHORT_CONTEXT VARCHAR(2500) NOT NULL,
  SERIALIZED_CONTEXT CLOB,
  constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
  references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ;
STEP_EXECUTION_ID  BATCH_STEP_EXECUTION 테이블에 대한 Foreign Key
SHORT_CONTEXT  SERIALIZED_CONTEXT
SERIALIZED_CONTEXT  직렬화 된 Execution Context

참고

- 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://dejavuhyo.github.io/posts/spring-batch/

- https://kitty-geno.tistory.com/158?category=1003990

- https://loosie.tistory.com/838

반응형
profile

JaeWon's Devlog

@Wonol

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!