티스토리 뷰

반응형

스프링 배치에서는 메타 데이터 테이블을 필수로 지정해 두었습니다.

그래서 스프링 배치를 실행할려면 메타 데이터 테이블을 생성해줘야 하는데요. 

 

어떤 데이터들을 저장하길래 스프링 배치에서 필수로 지정하였을까요??

 

스프링 배치의 메타 데이터에서는 아래와 같은 다양한 배치 어플리케이션의 정보를 얻을 수 있습니다.

  • 이전에 실행한 Job이 무엇인지
  • 최근 실패한 Job의 Batch Parameter가 무엇이었는지
  • 실패한 Job을 다시 실행한다면 어디서 부터 시작하면 될지

만약 메타 데이터를 저장하고 있지 않다면 최근에 실행한 배치 Job이 어느지점에서 실패하였는지 알기가 어렵고

이러한 배치 정보를 얻기 위해 로깅 시스템을 개발자가 직접 구현해야 합니다.

배치의 주요 비즈니스 로직구현보다 부가적인 로깅작업구현에 더 많은 리소스를 소모해야 할 수도 있습니다.

 

스프링 배치는 메타 데이터 테이블을 통해 개발자가 주요한 비즈니스 로직에 집중할 수 있게 
배치 어플리케이션을 운영하기 위해 필요한 정보를 저장해줍니다.

 

메타 테이블 구조는 아래와 같습니다

https://docs.spring.io/spring-batch/docs/3.0.x/reference/html/metaDataSchema.html

 

 

메타 데이터 테이블 생성


메타 데이터 테이블은 간단한 옵션으로 생성이 가능합니다.

 

application.yml

spring:
  batch:
    jdbc:
      initialize-schema: always

옵션 종류에는 always, embedded, never 3가지가 있습니다.

  • always: 스크립트를 항상 실행하여 스키마 생성
  • embedded: 내장 DB일 때만 실행
  • never: 스크립트 실행 안함 

스크립트의 경우 Intellij, Gradle를 사용하는 환경에서는 아래 순서를 따라 이동하시면 내용을 확인할 수 있습니다.

 

1. Project 탭 -> External Libraries 클릭

2. spring-batch-core 하위의 core 패키지로 이동

 

3. schema-*.sql 스크립트

저의 경우 MySQL을 사용하기 때문에 schema-mysql.sql 이 실행됩니다.

 

단, always 옵션을 사용하면 매번 스크립트가 실행되므로 개발환경에서만 사용하기를 추천드립니다.

실제 운영환경에서는 never 옵션을 사용하고 스크립트에 있는 DDL을 참고하여 직접 테이블을 생성해서 사용하는게 좋습니다.

 

테이블 생성 Schema는 아래 코드를 참고하시면 됩니다.

더보기
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;
 
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;
 
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;
 
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;
 
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;
 
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;
 
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);
 
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);
 
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);

 

 

메타 테이블 정보


1. BATCH_JOB_INSTANCE

CREATE TABLE BATCH_JOB_INSTANCE  (
  JOB_INSTANCE_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT,
  JOB_NAME VARCHAR(100) NOT NULL ,
  JOB_KEY VARCHAR(32) NOT NULL
);

BATCH_JOB_INSTANCE 테이블은 JobInstance객체와 관련된 정보를 저장하는 테이블입니다.

  • JOB_NAME: Job을 구성할 때 부여한 Job의 이름
  • JOB_KEY: JOB_NAME과 JobParamter를 합쳐서 해싱한 값을 저장

 

JobInstance 특성

  • Job이 실행될 때 생성되는 Job의 논리적 실행 단위 객체
  • Job의 설정과 구성은 동일하지만 Job이 실행되는 시점에 처리하는 내용은 다르기 때문에 Job의 실행을 구분해야 한다.
    • 예를 들어 하루에 한 번씩 coupon 정보를 삭제하는 Job이라면
    • 어제 실행되어 동작한 내용과 오늘 실행되어 동작한 내용이 다를것이기 때문에 매일 다른 JobInstance로 표현되어 집니다.

 

 

2. BATCH_JOB_EXECUTION_PARAMS

CREATE TABLE BATCH_JOB_EXECUTION_PARAMS  (
    JOB_EXECUTION_ID BIGINT NOT NULL ,
    PARAMETER_NAME VARCHAR(100) NOT NULL ,
    PARAMETER_TYPE VARCHAR(100) NOT NULL ,
    PARAMETER_VALUE VARCHAR(2500) ,
    IDENTIFYING CHAR(1) NOT NULL ,
    constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
    references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
);

BATCH_JOB_EXECUTION_PARAMS 테이블은 Job을 실행할 때 함께 포함되어 사용되는 JobParameter 객체의 내용을 저장하는 테이블입니다.

JobParameter의 이름, 타입, 값 에 대한 정보를 저장하고 있습니다.

 

JobParameter 특성

  • Job을 실행할 때 함께 포함되어 사용되는 파라미터를 가진 도메인 객체
  • JobInstance와 1:1 관계
  • JobParamter는 String , Date , Long , DOUBLE 4개의 타입을 지원
  • 기본적으로 하나의 Job은 동일한 JobParamter로 중복 실행할 수 없습니다.
    • 예를 들어 coupon을 삭제하는 잡에 JobParameter로 날짜값을 넘겨주는 경우
    • 2023-08-10일 JobParameter로 넘겨주었다면 또 다시 동일한 파라미터 값인 2023-08-10으로 Job 실행이 불가능합니다
    • 어?? 여기까지만 보면 그럼 뭔가 잘못된거가 아닌가 하실 수도 있는데요. 이를 해결하기 위한 방법으로 스프링 배치에서는 incremeter()를 지원하고 있으니 걱정하지 않으셔도 됩니다!

 

JobParamter 입력 실행 방법

--job.name=couponDeleteJob value1=coupon value2(long)=1L value3(date)=2023/08/09 value4(double)=1.5

JobParameter는 (Key=Value) 형식으로 입력하면 되는데요. Key값에 별도의 파라미터 타입을 명시하면 스프링 배치가 자동으로 타입 변환을 지원해줍니다.

만약 별도의 타입을 명시하지 않는 경우 String 타입으로 설정됩니다.

 

위의 JobParamter를 입력하여 실행하게 되면 실제 DB에는 아래와 같이 저장됩니다.

 

 

3. BATCH_JOB_EXECUTION

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,
  constraint JOB_INSTANCE_EXECUTION_FK foreign key (JOB_INSTANCE_ID)
  references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
);

BATCH_JOB_EXECUTION 테이블은 Job의 실행정보를 저장하는 테이블입니다.

스프링 배치내에서는 JobInstance에 대한 한번의 시도를 의미하는 JobExecution 객체를 통해 관리되어 집니다.

  • CREATE_TIME: JobExecution이 생성된 시점
  • START_TIME, END_TIME: 잡이 시작, 종료된 시점, Job 실행 도중 에러가 발생해 중단된 경우 END_TIME 값은 NULL값으로 저장됩니다
  • STATUS: 실행 상태, EXIT_CODE: 실행 종료코드, EXIT_MESSAGE: status가 실패일 경우 실패 원인 내용을 저장
  • LAST_UPDATED: 마지막 실행 시점

 

JobExecution 특성

  • Job 실행 중에 발생한 정보들을 저장하고 있는 객체
    • 시작시간(START_TIME), 종료시간(END_TIME), 종료 상태(STATUS) 등의 속성을 가지고 있다.
  • JobExecution 실행 상태 결과가 'COMPLETED'면 JobInstance 실행이 완료된걸로 간주한다.
  • JobExecution 실행 상태 결과가 'FAILED'면 JobInstance 실행이 완료되지 않은 것으로 간주해 재실행이 가능하다.
  • JobInstance와 JobExecution은 1:N관계이다.

 

4. BATCH_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은 Step의 실행정보를 저장하는 테이블입니다.

  • BATCH_JOB_EXECUTION과 대부분 비슷하지만 Step을 대한 정보를 저장한다는 차이점이 있다.
  • COMMIT_COUNT: 트랜잭션 당 커밋 수
  • READ_COUNT: 실행도중 Read한 Item 수
  • FILTER_COUNT: 실행도중 필터링 된 Item 수
  • WRITE_COUNT: 실행도중 저장되고 커밋된 Item 수
  • READ_SKIP_COUNT: Read 과정에서 Skip된 Item 수
  • PROCESS_SKIP_COUNT: Process 과정에서 Skip된 Item 수
  • WRITE_SKIP_COUNT: Write 과정에서 Skip된 Item 수
  • ROLLBACK_COUNT: rollback이 일어난 수

 

StepExecution 특성

  • Step 실행 중에 발생한 정보들을 저장하고 있는 객체
  • Job이 재시작하더라도 COMPLETED(완료)된 Step은 재 실행되지 않는다.
  • 이전 단계의 Step이 실패해서 현재 Step을 실행하지 않았다면 StepExecution을 생성하지 않는다.
    • Step이 실제로 시작됐을 때만 StepExecution을 실행한다.
  • JobExecution과 1: N의 관계
    • Step의 StepExecution 이 모두 정상적으로 완료 되어야 JobExecution이 정상적으로 완료된다
    • Step의 StepExecution 중 하나라도 실패하면 JobExecution 은 실패한다

 

5. BATCH_JOB/STEP_EXECUTION_CONTEXT

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;

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;

각각 Job, Step의 실행과 관련된 정보를 저장하는 테이블입니다.

  • SHORT_CONTEXT: Job/Step의 실행 상태정보, 공유 데이터 등의 정보를 문자열로 저장
  • SERIALIZED_CONTEXT: 직렬화된 전체 컨텍스트

 

좀 더 자세한 사항은 공식문서를 참고하시면 됩니다.

그렇지만 공식문서보다 직접 배치를 실행해 DB에 저장되는 값을 보는것이 이해하는데 더 많은 도움을 줄거라고 생각하기 때문에 직접 실행해보시는걸 추천드립니다!! 감사합니다.

https://docs.spring.io/spring-batch/docs/3.0.x/reference/html/metaDataSchema.html

 

Appendix B. Meta-Data Schema

The Spring Batch Meta-Data tables very closely match the Domain objects that represent them in Java. For example, JobInstance, JobExecution, JobParameters, and StepExecution map to BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_JOB_EXECUTION_PARAMS, and BA

docs.spring.io

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함