배치의 정의와 필요한 이유
1. 배치의 정의
배치(Batch)는 대량의 데이터를 정기적이고 반복적으로 처리하는 프로그램입니다. 주로 사용자가 없는 새벽 시간대에 실행되며, 대규모 데이터의 처리, 집계, 변환 등 비즈니스 로직을 실행하는 데 활용됩니다.
2. 배치 애플리케이션이 필요한 이유x
2.1 WAS와 배치의 구분
- WAS (Web Application Server)는 사용자 요청을 실시간으로 처리하는 서버입니다.
- 하지만 배치와 같이 대규모 데이터를 처리하거나 비즈니스 로직을 길게 실행해야 하는 작업은 WAS에서 실행하기 적합하지 않습니다.
주요 이유는 다음과 같습니다:- 성능 문제: 실시간 요청을 처리하는 서버에서 대량 데이터 작업을 수행하면, 응답 속도가 느려져 사용자 경험이 저하됩니다.
- 안정성 문제: 장시간 실행되는 작업은 서버 부하를 유발하거나 실패 시 서비스 장애로 이어질 수 있습니다.
- 스케줄링 필요: 배치는 정해진 시간에 주기적으로 실행되므로 스케줄링이 필요합니다.
2.2 배치가 필요한 시나리오
- 커머스 사이트의 매출 집계: 하루 50만~100만 건의 거래 데이터를 실시간으로 조회하려면 서버 부하가 큽니다. 대신, 새벽에 전날 데이터를 집계해 미리 저장해두고 요청 시 바로 제공하면 성능을 최적화할 수 있습니다.
- ERP 데이터 전송: 사내 데이터와 외부 시스템 간 연동 작업을 일정 주기로 처리 할 때, 사용하기도 합니다.
3. Spring Batch와 다른 스케줄링 기술의 차이점
기술 | Spring Batch | Spring Scheduler | Spring Quartz |
---|---|---|---|
주요 목적 | 대규모 데이터 처리 및 워크플로 관리 | 단순한 반복 작업 관리 | 고급 스케줄링 및 작업 의존성 관리 |
구성 요소 | Job, Step, Reader, Processor, Writer | @Scheduled 어노테이션 | Job, Trigger |
상태 관리 | 지원 (Job Execution 상태 기록) | 미지원 | 지원 (Persistent Job Store 활용 시) |
분산 처리 | 기본 지원 | 미지원 | 클러스터링 지원 |
적용 사례 | 대규모 배치 작업, 데이터 처리 파이프라인 | 간단한 반복 작업 | 복잡한 스케줄링, 분산 환경 작업 |
4. Spring Batch의 구성 요소
Spring Batch는 데이터를 읽고, 처리하고, 저장하는 작업을 단계적으로 수행합니다.
Job
- 여러 개의 Step을 포함하며 배치의 최상위 개념이다.
JobInstance
- Job의 실행 단위를 말합니다. Job을 실행시키면 하나의 JobInstance가 생성됩니다. BATCH_JOB_INSTANCE 테이블에 관련된 정보가 기록됩니다.
JobParameters
- JobInstance를 구별하는 식별자이자, JobInstance에 전달되는 매개변수입니다.
JobExecution
- JobInstance에 대한 실행 시도에 대한 객체입니다. BATCH_STEP_EXECUTION 테이블에 관련된 정보가 기록됩니다.
Tasklet
단일 작업을 실행하는 로직입니다.
Step
- Job의 배치처리를 정의하고 순차적인 단계를 캡슐화합니다. Job은 최소 1개 이상의 Step을 가지며, Job의 일괄 처리를 제어하는 모든 정보가 들어 있습니다. 보통 Tasklet 혹은 Reader-Processor-Writer로 구성됩니다.
StepExecution
- JobExecution과 동일하게 Step 실행 시도에 대한 객체를 나타냅니다. StepExecution은 JobExecution과 동일하게 Step 실행 시도에 대한 객체를 나타냅니다. 하지만 Job이 여러개의 Step으로 구성되어 있을 경우 이전 단계의 Step이 실패하게 되면 다음 단계가 실행되지 않음으로 실패 이후 StepExecution은 생성되지 않습니다. StepExecution 또한 JobExecution과 동일하게 실제 시작이 될 때만 생성됩니다. StepExecution에는 JobExecution에 저장되는 정보 외에 read 수, write 수, commit 수, skip 수 등의 정보들도 저장이 됩니다.
ExecutionContext
- ExecutionContext란 Job에서 데이터를 공유 할 수 있는 데이터 저장소입니다. Spring Batch에서 제공하느 ExecutionContext는 JobExecutionContext, StepExecutionContext 2가지 종류가 있으나 이 두가지는 지정되는 범위가 다릅니다. JobExecutionContext의 경우 Commit 시점에 저장되는 반면 StepExecutionContext는 실행 사이에 저장이 되게 됩니다. ExecutionContext를 통해 Step간 Data 공유가 가능하며 Job 실패시 ExecutionContext를 통한 마지막 실행 값을 재구성 할 수 있습니다.
JobRepository
JobRepository는 위에서 말한 모든 배치 처리 정보를 담고있는 매커니즘입니다. Job이 실행되게 되면 JobRepository에 JobExecution과 StepExecution을 생성하게 되며 JobRepository에서 Execution 정보들을 저장하고 조회하며 사용하게 됩니다.
JobLauncher
JobLauncher는 Job과 JobParameters를 사용하여 Job을 실행하는 객체입니다.
ItemReader
ItemReader는 Step에서 Item을 읽어오는 인터페이스입니다. ItemReader에 대한 다양한 인터페이스가 존재하며 다양한 방법으로 Item을 읽어 올 수 있습니다.
ItemWriter
ItemWriter는 처리 된 Data를 Writer 할 때 사용한다. Writer는 처리 결과물에 따라 Insert가 될 수도 Update가 될 수도 Queue를 사용한다면 Send가 될 수도 있다. Writer 또한 Read와 동일하게 다양한 인터페이스가 존재한다. Writer는 기본적으로 Item을 Chunk로 묶어 처리하고 있습니다.
ItemProcessor
Item Processor는 Reader에서 읽어온 Item을 데이터를 처리하는 역할을 하고 있다. Processor는 배치를 처리하는데 필수 요소는 아니며 Reader, Writer, Processor 처리를 분리하여 각각의 역할을 명확하게 구분하고 있습니다.
5. Spring Batch의 메타 테이블
Spring Batch는 실행 상태와 결과를 메타 테이블에 저장해 관리합니다.
이 메타 테이블들은 자동으로 생성되며 작업의 상태 추적 및 재시도를 가능하게 합니다.
- BATCH_JOB_INSTANCE: Job의 인스턴스 정보
CREATE TABLE BATCH_JOB_INSTANCE (
JOB_INSTANCE_ID BIGINT PRIMARY KEY ,
VERSION BIGINT,
JOB_NAME VARCHAR(100) NOT NULL ,
JOB_KEY VARCHAR(2500)
);
- BATCH_JOB_EXECUTION: 실행된 Job의 시작 및 종료 시간, 상태 정보
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)
);
- 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 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)
);
- BATCH_STEP_EXECUTION : Step의 실행 정보
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)
);
- BATCH_JOB_EXECUTION : JobExcution에 관련된 모든 정보를 저장하고 있습니다. JobExcution은 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)
);
- 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)
);
- 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)
);
6. Spring Batch와 스케줄링 기술의 결합
Spring Batch는 배치를 정의하는 데 사용되며, Spring Scheduler 또는 Spring Quartz와 결합해 정해진 시간에 배치를 실행할 수 있습니다.
예시 코드: Spring Batch + Spring Scheduler
@Component
public class SchedulerConfig {
@Scheduled(cron = "0 0 1 * * ?") // 매일 새벽 1시 실행
public void runBatchJob() {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
try {
jobLauncher.run(batchJob, jobParameters);
} catch (Exception e) {
e.printStackTrace();
}
}
}
예시 코드: Spring Batch + Spring Quartz
@Configuration
public class QuartzConfig {
@Bean
public JobDetail batchJobDetail() {
return JobBuilder.newJob(QuartzBatchLauncher.class)
.storeDurably()
.build();
}
@Bean
public Trigger batchJobTrigger() {
return TriggerBuilder.newTrigger()
.forJob(batchJobDetail())
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 1 * * ?"))
.build();
}
}
@Component
public class QuartzBatchLauncher implements Job {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job batchJob;
@Override
public void execute(JobExecutionContext context) {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
try {
jobLauncher.run(batchJob, jobParameters);
} catch (Exception e) {
e.printStackTrace();
}
}
}
7. Batch 실행 흐름 컨트롤: Next, Flow, Decide
Spring Batch는 작업의 흐름을 세밀하게 제어할 수 있습니다.
- Next: 순차적으로 Step 연결
.start(stepA)
.next(stepB)
.build();
- Flow: 오류가 발생할 경우 특정 Step으로 분기
.from(stepA).on("FAILED").to(stepC)
.from(stepA).on("*").to(stepB)
- Decide: 조건에 따라 다양한 분기 처리
.from(stepA).next(decisionStep).on("CONDITION_1").to(stepB)
.from(decisionStep).on("CONDITION_2").to(stepC)
결론
Spring Batch는 대규모 데이터를 효율적으로 처리하기 위한 강력한 도구이며, 스케줄링 기술(Spring Scheduler, Quartz)과 결합해 실무에 적합한 배치 시스템을 구축할 수 있습니다.
'Framework > Spring' 카테고리의 다른 글
[Batch] Spring Batch Scope의 개념과 Job Parameter 사용 방법 (0) | 2024.11.27 |
---|---|
[Spring] Spring Boot 환경설정 가이드 (2) | 2024.09.23 |
[Spring] Spring 프레임워크란 무엇인가? (1) | 2024.09.20 |
[Spring] IoC와 DI란 무엇인가? (0) | 2024.09.20 |
[Test] Spring Boot 환경에서의 유닛테스트와 통합테스트, 슬라이스 테스트 (1) | 2024.09.19 |
댓글