개발공부/SPRING
[Spring Batch] Spring Batch 개념
키크니개발자
2023. 6. 4. 16:53
왜 스프링 배치를 사용하는가?
- 배치 처리는 컴퓨터에서 사람과 상호 작용 없이 이어지는 프로그램의 실행 → 한번 요청으로 그 시스템 내에서 종료가 됨
- 사용자와의 상호 작용이 주력인 웹 애플리케이션과는 지향점이 다름
- web : 실시간 처리 / QA 용이성
- batch : 후속 처리 / QA 복잡성
언제 사용하는가?
- 일정 주기로 실행되어야 할 때
- 웹어플리케이션으로 실시간 처리가 어려운 대량의 데이터를 처리할 때
- 배치는 대량의 데이터를 처리하기 위해서 여러 가지 기능을 제공 → 개발자는 업무 로직의 구현에만 집중하고 공통적인 기반 기술은 프레임워크가 담당
- pageSize, chunkSize 등이 프레임워크 단위에서 지원이 됨
- 하지만 Quartz는 지원해주지 않음 -> Spring Batch와 Quartz를 함께 사용하려면 Quartz 스케줄러를 스프링 빈으로 등록하고, Spring Batch Job을 Quartz Job으로 래핑하여 Quartz 스케줄러에서 실행하도록 설정해야 합니다.
스프링 배치 아키텍처
- 실제 비지니스 로직이 들어감 → 개발자는 업무 로직의 구현에만 집중하고 공통적인 기반기술은 프레임워크가 담당
- 배치 meta 테이블 정보, Job을 실행, 모니터링, 관리하는 API로 구성
- JobLauncher, Job, Step, Flow 등이 속함
- Application, Core 모두 공통 Infrastructure 위에서 빌드
- Job 실행의 흐름과 처리를 위한 틀을 제공 - Reader, Processor, Writer, Skip, Retry 등
스프링 배치 메타 테이블
- 스프링 배치의 실행 및 관리를 위한 목적으로 여러 도메인들 - Job, Step, JobParameter 의 정보들을 저장, 업데이트, 조회할 수 있는 스키마
- 과거, 현재의 실행에 대한 성공과 실패 여부 등을 관리 → 배치 운용에 있어 리스크 발생 시 빠른 대처 가능
- Job 관련 테이블
- batch_job_instance
- job이 실행될 때 jobInstance 정보가 저장 → job_name / job_key를 키로 하여 하나의 데이터가 저장 → 그래서 동일한 job_name과 job_key로 중복 저장될 수 없음
- job_name: job을 구성할 때 부여하는 이름
- job_key: job_name과 jobParameter를 합쳐 해싱한 값
- batch_job_execution
- job의 실행정보가 저장 → job 생성 시간, 시작 시간, 종료 시간, 실행 상태(성공했는지.. 실패했는지..), 종료 메시지 등을 관리
- batch_job_execution_param
- job과 함께 실행되는 jobParamter 정보를 저장
- batch_job_execution_context
- job의 실행동안 상태정보, 공유 데이터를 직렬화(json)해서 저장
- step간 공유 가능
- batch_job_instance
- Step 관련 테이블
- batch_step_execution
- step의 실행정보가 저장 → step 생성 시간, 시작 시간, 종료 시간, 실행상태, 종료 메시지 등을 관리
- batch_step_execution_context
- step의 실행동안 상태정보를 직렬화(json)해서 저장
- step 별로 저장되며 step간 공유 불가능
- batch_step_execution
Job / Step / Tasklet
- Job
- 배치 계층에서 가장 상위에 있는 개념 → 하나의 배치 작업 자체를 의미
- @JobConfiguraion을 통해 생성되는 객체 단위 → 배치작업을 어떻게 구성하고 실행할 것인지 전체적으로 설정하고 명세해 놓은 객체
- 여러 step을 포함하고 있는 container 역할 → 반드시 하나의 step이 있어야함
- 기본 구현체
- SimpleJob : 순차적으로 Step을 실행시키는 Job
- FlowJob : 특정한 조건과 흐름에 따라서 Step을 구성하고 실행시키는 Job
- jobInstance
- job의 설정과 구성은 동일하지만 job이 실행되는 시점에 처리하는 내용은 다름 → 예를 들어서 5분마다 실행되는 job은 서로 다른 jobInstance를 가져야 함
- 처음 시작하는 job Name + jobParameter의 경우 새로운 jobInstance 리턴, 이전과 동일한 job Name + jobParameter의 경우 이미 존재하는 jobInstance 리턴
- 내부적으로 jobName + jobKey를 통해서 jobInstance를 얻음
- batch_ job_instance 테이블과 매핑
- jobParamter
- job을 실행할 때 함께 포함되어 사용되는 파라미터를 가진 도메인 객체
- jobParamter와 jobInstance는 1:1관계
- jobParameter를 사용하기 위해서 @JobScope, @StepScope 선언 필수
- batch_job_execution_param 테이블과 매핑
- jobExecution
- jobInstance 실행 중 발생한 정보들을 저장하고 있는 객체
- jobParamter 정보, executionContext 정보, 시작 시간, 종료 시간, 상태(시작됨, 완료, 실패)의 속성
- jobExecution의 실행 상태 결과에 따라서
- ‘COMPLETED’면 jobInstance 실행이 완료된 것으로 간주해서 재실행 불가
- ‘FAILED’면 jobInstance 실행이 완료되지 않은 것으로 간주해서 재실행 가능 → jobParamter가 동일한 값일 지라도 jobInstance 계속 실행 가능
- batch_job_execution 테이블과 매핑
- Step
- job을 구성하는 독립적인 하나의 단계로 실제 배치 처리를 정의하고 컨트롤하는데 필요한 정보를 가지고 있는 객체
- 단순한 단일 태스크 뿐 아니라 입력, 처리, 출력 관련된 복잡한 비지니스 로직을 포함하는 모든 설정들을 담고 있음
- 기본 구현체
- TaskletStep
- 가장 기본이 되는 클래스로서 Tasklet 타입 구현체들을 제어
- return this.stepBuilderFactory.get("step").tasklet(myTasklet()).build() → 직접 생성한 tasklet 실행
- return this.stepBuilderFactory.get("step").<>chunk(100).reader(reader()).writer(wrtier()).build() → ChunkOrientedTasklet 실행
- PartitionStep : 멀티 스레드 방식으로 Step을 여러 개로 분리해서 실행
- JobStep : step 내에서 job을 실행
- FlowStep : step 내에서 flow를 실행
- TaskletStep
- StepExecution
- step에 대한 한번의 시도를 의미하는 객체로 step 실행 중에 발생한 정보들을 저장하고 있는 객체
- jobExecution 정보, executionContext 정보, 시작 시간, 종료 시간, 상태, commit count, rollback count 등의 속성
- step이 시도될 때마다 stepExecution 객체가 생성 → 이전 단계 step이 실패했다 stepExecution을 생성하지 않고 재활용
- job이 재시작하더라도 이미 성공적으로 완료된 step은 재실행되지 않고 실패한 step만 실행
- jobExecution과의 관계
- step의 stepExecution이 모두 정상적으로 완료 되어야 JobExecution이 정상적으로 완료 → 하나라도 실패하면 jobExcecution은 실패
- batch_step_execution 테이블과 매핑
- ItemStream
- open, update, close 메소드가 있는데 ItemReader와 ItemWriter 처리 과정 중 상태를 저장하다가 오류가 발생하면 상태를 참조해서 실패한 곳에서 재시작하도록 지원
- ExecutionContext를 매개변수로 받아서 상태 정보를 업데이트
- ItemReader와 ItemWriter 는 ItemStream을 구현
- executionContext (jobExecution, stepExecution 클래스에 속해있음)
- 프레임워크에서 유지 및 관리하는 키/값으로 된 컬렉션으로 StepExecution, JobExecution 객체의 상태를 저장하는 공유 객체
- Map<String, Object> map = new ConcurrentHashMap<>();
- db에 직렬화 한 값으로 저장 → {"key":"value"} - batch_job_execution_context, batch_step_execution_context
- 공유 범위
- step - 각 step의 stepExecution 클래스에 저장 → step간 공유할 수 없음
- job - 각 job의 jobExecution에 저장 → job간 공유할 수 없음, step간 공유 가능
- stepExecution의 경우 내부에 jobExecution 속성이 있어서 jobExecution에 정의된 executionContext 접근 가능 → 그래서 공유가 가능
- 프레임워크에서 유지 및 관리하는 키/값으로 된 컬렉션으로 StepExecution, JobExecution 객체의 상태를 저장하는 공유 객체
반응형