회사에서 업무를 하나씩 배우고 맡게 되면서, 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 ?
Spring Batch 는 Scheduler 가 아니기 때문에 비교 대상은 아니다.
- Spring Batch는 Batch Job 을 관리하지만, 실질적으로 이 Job을 구동하거나 실행시키는 기능은 지원하지 않는다.
- Spring 에서 해당 Batch Job 을 실행시키기 위해서는, Quartz, Scheduler 등 전용 Scheduler 를 사용해야 한다.
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.
- Tasklet
- 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 를 통해 마지막 실행 값을 재구성 할 수 있음.
- JobExecutionContext
- JobRepository
- 수행되는 Job 의 모든 정보를 담고 있는 저장소.
- 어떠한 Job 이 언제 수행되었고, 언제 종료하고, 몇 번 실행되었고, 실행에 대한 결과가 어떤지 등의 Batch 수행과 과련된 모든 Meta Data 가 저장.
- Job 이 실행되게 되면 JobRepository 에 JobExecution 과 StepExecution 을 생성하고, JobRepository 에서 Execution 정보들을 저장하고 조회하며 사용. - Item
- 처리할 데이터의 가장 작은 구성 요소.
- 예를들면, 파일의 한줄, DB의 한 Row, XML 의 특정 element.
- 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://dejavuhyo.github.io/posts/spring-batch/
'BackEnd > Spring Batch' 카테고리의 다른 글
[Spring] Spring Batch 장애 회고(Feat. ChunkListner 사용하기) (0) | 2024.07.12 |
---|---|
[Spring] Spring Batch JobParameter 활용 하기(With. Custom 하기, 공통 관리하기) (1) | 2023.10.27 |
[Spring] Spring Batch 사용해보기(3) - step(tasklet, chunk) (0) | 2022.09.18 |
[Spring] Spring Batch 사용해보기(2) - step(skip, retry) (0) | 2022.09.14 |
[Spring] Spring Batch 사용해보기(1) - 환경구성, 기본구현 (1) | 2022.09.08 |