• Batch 
    • 일괄처리
  • 사용 예
    • 엄청나게 큰 데이터를 가공해야 하는데 예를 들어 그 작업을 하루에 1번 정도 해줘야 한다. 
      • 엄청나게 큰 데이터를 가공해야 한다 ? 
        • CPU, I/O 등의 자원 처리에 서버 부하가 발생 
        • Request 처리를 올바르게 할 수 없다. 
        • 데이터 처리 중에 실패 발생하면, 다시 처음부터 하는게 아니라 끝난 지점부터하는게 좋음 (5만1번째)
      • 하루에 딱 1번 한다 ?
        • 하루에 한번만 돌게 하는 것을 구현하려고 API를 구성하는 것은 낭비일 수 있음 
        • 다른 사람이 한번 더 돌리는 실수를 막아야 함
  • SpringBatch는
    • '단발성으로 대용량의 데이터를 처리하는 어플리케이션' 이다.
      • Spring MVC를 사용함으로써 비즈니스 로직에 최대한 집중할 수 있었던 것 처럼 Spring Batch를 이용하면 배치 어플리케이션을 동작하는 데 필요한 로직에만 집중할 수 있다.
      • 예를 들어, 이미 실행된 경우 재실행을 불가능 하게 한다거나, 실패된 지점에서 부터 다시 동작시키게 할 수 있다거나... 이런 기능들을 SpringBatch가 쉽게 할 수 있도록 도와준다. 
      •  
  • Batch Application의 조건
    • 대용량 데이터 - 대용량의 데이터를 가져오거나 전달, 계산 등의 처리를 함 
    • 자동화 - 사용자 개입을 최소로 줄여 최대한 자동으로 동작될 수 있도록 한다.
    • 견고성 - 잘못된 데이터를 충돌/중단 없이 처리
    • 신뢰성 - 잘못된 부분을 추적할 수 있음 (로깅 / 알림)
    • 성능 - 지정된 시간 내에 처리, 다른 어플리케이션을 방해하지 않는다.

아래의 그림과는 표현한 방식이 살짝 다르다.
Job과 Step은 작업의 최소 단위,  Step을 통해 데이터 읽기/가공/결과기록 등의 로직을 묶어서 관리한다. Chunk는 한 번의 operation을 통해 다룰 데이터의 집합으로 각 Step은 설정에 정의된 Chunk 단위에 따라 데이터를 읽어 들이고 가공한 후 기록한다. Step의 설정에서 Chunk의 크기를 결정하는데 이는 데이터베이스의 한 row일 수도 있고, CSV 파일의 한 줄일 수도 있다. Chunk는 트랜잭션 관리 단위이기도 하여 마지막 처리 시점에 TX를 커밋하거나 롤백한다. ItemReader<Input> 은 작업 대상이 될 데이터를 읽어 들이는 컴포넌트이다. ItemProcessor<Input,Output>은 로직에 따라 가공하고, 변경된 데이터를 리턴한다. ItemWriter<Output>은 완성된 데이터를 정해진 곳에 저장/색인한다.

 

  • Batch Application 생성 - Simple ver.

Spring Initializer를 이용해 위의 세팅으로 프로젝트 생성

 

SpringBatch의 여러 기능을 쓰려면 필수로 추가해야하는 어노테이션
Job 생성과 Step 생성

run을 해보면..

 

log.info(">>>>> This is Step1") 가 잘 수행되어있음

 

 

 

 

 

  • Batch Application 생성 - hard ver.
    • PostgreSQL 환경에서 Spring Batch 실행해보기 
    • 먼저, Spring Batch를 작동하기 위해 필요한 메타 데이터 테이블을 세팅한다. 
      • Spring Batch 의 메타데이터는..
        • 이전에 실행한 Job에 대한 기록
        • 실패한 Batch Parameter 기록, 성공한 Job 기록
        • 재실행시 시작해야 될 포인트 기록
        • Job이 갖고 있는 Step에 대한 Histroy tracking (성공/실패 Step 기록)

소스 라이브러리에서 spring-batch-core 디렉토리 안에 있다.

 

더보기

-- Autogenerated: do not edit this file

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)
) ;

CREATE TABLE BATCH_JOB_EXECUTION (
JOB_EXECUTION_ID BIGINT NOT NULL 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(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED TIMESTAMP,
JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ;

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 TIMESTAMP 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)
) ;

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 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(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED TIMESTAMP,
constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;

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)
) ;

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)
) ;

CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ MAXVALUE 9223372036854775807 NO CYCLE;
CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ MAXVALUE 9223372036854775807 NO CYCLE;
CREATE SEQUENCE BATCH_JOB_SEQ MAXVALUE 9223372036854775807 NO CYCLE;

위의 쿼리문을 이용해 table을 생성해준다. 나는 AWS RDS를 이용해 PostgreSQL을 설치해 주었다. 

 

application.yml에 datasource 설정 완료

 

 

참조

medium.com/myrealtrip-product/spring-batch-%EC%B2%98%EC%9D%8C%EB%B6%80%ED%84%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-3c6a5db0646d

 

Spring Batch, 처음부터 시작하기

커머스 서비스 개발자를 위한 Spring Batch 입문

medium.com

jojoldu.tistory.com/325?category=902551

 

2. Spring Batch 가이드 - Batch Job 실행해보기

이번 시간에는 간단한 Spring Batch Job을 생성 & 실행하면서 전반적인 내용을 공부해보겠습니다. 작업한 모든 코드는 Github에 있으니 참고하시면 됩니다. 2-1. Spring Batch 프로젝트 생성하기 기본적인

jojoldu.tistory.com

 

+ Recent posts