Spring Batch 이란?
Spring Batch 개요
- 스프링 배치는 스프링을 만든 Pivotal의 프로젝트 중 하나이다.
- 이전 스케줄러에서 하던 작업을 대용량 배치로 빼서 만든 프레임워크이다.
- 기존 스케줄링 작업은 로그 확인이 어려웠다.
- Spring Batch는 일괄적 데이터 처리 가능하다.
- 스키마(mysql.sql)을 통해 spring batch 메타 정보들 관련 table 생성할 수 있다.
Spring Batch 기본 개념
Job
- Batch의 가장 큰 작업의 담위이며, 실행의 단위가 된다.
- Bean을 통해 Job을 등록하고 파라미터 설정으로 Job 실행 가능하다.
- N개의 Job을 생성할 수 있다.
- Job은 N개의 Step으로 구성되어 있다. 최소 1개의 Step을 가져야 한다. 엄청나게 복잡한 Job이 아닌 이상 2-10개의 Step을 권장한다.
Step
- Job안에 속하게 되는 작업이다.
- Step은 Tasklet 처리 방식과 Chunk 지향 처리 방식(reader, processor, writer)을 지원하고 있다.
- Step은 읽기 > 가공하기 > 쓰기의 묶음이다. 이 묶음을 Chunk processiong이라고 부르는데 하나의 트랜잭션으로 이해하면 된다. 바로 이 Chunk processing의 재시작의 핵심이다.
Tasklet
- Step안에 속하는 작업이다.
Chunk
-
Chunk란 처리 되는 커밋 row 수를 의미한다.
-
Batch 처리에서 커밋 되는 row 수라는건 chunk 단위로 Transaction을 수행하기 때문에 실패시 Chunk 단위 만큼 rollback이 되게 된다.
-
Chunk 지향 처리에서는 다음과 같은 3가지 시나리오로 실행된다.
- 읽기(Read) — Database에서 배치처리를 할 Data를 읽어온다
- 처리(Processing) — 읽어온 Data를 가공,처리를 한다 (필수사항X)
- 쓰기(Write) — 가공,처리한 데이터를 Database에 저장한다.
chunk, page 개념
- page : 처리할 데이터 중 일정 개수만큼 조회
- chunk : 조회한 데이터를 일정 개수만큼 처리 후 입력
page = chunk * n
으로 세팅해야 성능적으로 좋다고 한다. 보편적으로는page = chunk
이다.
ItemReader
- ItemReader는 말 그대로 데이터 읽기를 담당한다.
- 필수이다.
- 데이터 조회 타입
- ItemReader 주요 구현체들
- CursorItemReader : (stream)방식으로 1건씩 처리한다.
- PagingItemReader : (page) 사이즈 만큼 조회하여 처리한다.
ItemProcessor
- ItemProcessor는 ItemReader에게서 Object를 넘겨받아 원하는 방식으로 가공 후에 ItemWriter에 넘겨주는 역할을 하며, 한번에 하나의 아이템을 처리한다.
- 필수가 아닌다.
- 조회 데이터 후 가공한다.
- ItemProcessor 주요 구현체들
- CompositeItemProcessor : 프로세스를 체이닝 처리하여 순차적 진행한다.
ItemWriter
- ItemReader 혹은 ItemProcessor가 ItemWriter로 데이터를 넘겨주면 리스트에 차곡차곡 쌓아놓는다.
- 필수이다.
- 데이터를 저장한다.
- ItemWriter 구현체들
- CompositeItemWriter
- FlatFileItemWriter
- HibernateItemWriter
- JdbcBatchItemWriter
- JsonFileItemWriter
- MongoItemWriter
JobLauncher
Job을 실행하는 역활을 한다.
JobRepository
Job, Step 등의 배치 작업에 대한 메타 정보를 처리하는 인터페이스이다.
메타정보는 Spring Batch가 제공하는 핵심 기능 중 하나이다.
Spring Batch Meta-Data Schema
Spring Batch에는 Meta-Data가 Table 6개, Sequence 3개가 존재한다. 여기에 Spring BatchJob이 실행 될 때마다 실행된 Job에 대한 다양한 정보들이 저장되게 된다.
일반적으로는 Meta-Data Table이 없이는 Spring Batch를 실행시킬 수 없으나, 이는 필요에 따라 커스터마이징을 통해 Meta-Data Table이 없이도 실행되게 만들 수 있다. 하지만, 시스템 운영을 하면서 배치가 실행 및 실패의 이력 등의 정보를 확인해야 하기에 필요 반듯이 필요할 것이다.
spring-batch-core
에 Meta-Dat Table들의 스키마를 DBMS별 schema-{DBMS}.sql
파일들이 포함되어 있다.
(IDE에서 schema-
로 시작하는 파일들을 찾아 보면 나올 것이다.)
여기에서는 MySQL의 기준으로 Table Create문을 확익해 보도록 하겠다. MySql 스키마 파일은 schema-mysql.sql
이다.
(참고로, MySql에서는 sequence가 존재하지 않기에 Sequense 역할을 하기 위한 Table도 만들어야 한다.)
BATCH_JOB_INSTANCE
BATCH_JOB_INSTANCE 테이블에는 JobInstance에 관련된 모든 정보가 포함되어 있다. 또한 해당 Table은 전체 계층 구조의 최상위 역할을 한다.
CREATE TABLE BATCH_JOB_INSTANCE (
JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT ,
JOB_NAME VARCHAR(100) NOT NULL,
JOB_KEY VARCHAR(32) NOT NULL,
constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
) ENGINE=InnoDB;
BATCH_JOB_INSTANCE의 Primary Key는 BATCH_JOB_SEQ에 의해 생성된다.
CREATE TABLE BATCH_JOB_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_JOB_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_SEQ);
BATCH_JOB_EXECUTION
BATCH_JOB_EXECUTION테이블에는 JobExcution에 관련된 모든 정보를 저장하고 있다. JobExcution은 JobInstance가 실행 될 때마다 시작시간, 종료시간, 종료코드 등 다양한 정보를 가지고 있다
CREATE TABLE BATCH_JOB_EXECUTION (
JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT ,
JOB_INSTANCE_ID BIGINT NOT NULL,
CREATE_TIME DATETIME(6) NOT NULL,
START_TIME DATETIME(6) DEFAULT NULL ,
END_TIME DATETIME(6) DEFAULT NULL ,
STATUS VARCHAR(10) ,
EXIT_CODE VARCHAR(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME(6),
JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ENGINE=InnoDB;
BATCH_JOB_EXECUTION의 Primary Key는 BATCH_JOB_EXECUTION_SEQ에 의해 생성된다.
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);
BATCH_JOB_EXECUTION_PARAMS
BATCH_JOB_EXECUTION_PARAMS 테이블에는 Job을 실행 시킬 때 사용했던 JobParameters에 대한 정보를 저장하고 있다.
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(6) 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)
) ENGINE=InnoDB;
BATCH_STEP_EXECUTION
BATCH_JOB_EXECUTION테이블에는 StepExecution에 대한 정보를 저장하고 있다. BATCH_JOB_EXECUTION 테이블과 여러 면에서 유사하며 STEP을 EXECUTION 정보인 읽은 수, 커밋 수, 스킵 수 등 다양한 정보를 추가로 담고 있다.
CREATE TABLE BATCH_STEP_EXECUTION (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT NOT NULL,
STEP_NAME VARCHAR(100) NOT NULL,
JOB_EXECUTION_ID BIGINT NOT NULL,
START_TIME DATETIME(6) NOT NULL ,
END_TIME DATETIME(6) 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(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME(6),
constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
BATCH_STEP_EXECUTION의 Primary Key는 BATCH_STEP_EXECUTION_SEQ에 의해 생성된다.
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_STEP_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_STEP_EXECUTION_SEQ);
BATCH_JOB_EXECUTION_CONTEXT
BATCH_JOB_EXECUTION_CONTEXT테이블에는 JobExecution의ExecutionContext 정보가 들어있다.이 ExecutionContext 데이터는 일반적으로 JobInstance가 실패 시 중단된 위치에서 다시 시작할 수 있는 정보를 저장하고 있다.
CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT TEXT ,
constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ENGINE=InnoDB;
BATCH_STEP_EXECUTION_CONTEXT
BATCH_STEP_EXECUTION_CONTEXT테이블에는 StepExecution의 ExecutionContext 정보가 들어있다. 이 ExecutionContext 데이터는 일반적으로 JobInstance가 실패 시 중단된 위치에서 다시 시작할 수 있는 정보를 저장하고 있다.
CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT (
JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT TEXT ,
constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;