배경
개발자 생활을 하기 전 학생 시절에는 배치를 사용해 본 적이 없었지만, 개발자가 되고 나니 배치는 반드시 짜야하는 숙명 아닌 숙명이 되어버렸다. 15시마다 모든 재고를 폐기처리할 때 사용하거나, 배송 기사에게 알림톡을 보내는 용도로 사용하거나, 정산 쪽 개발을 하면서 정해놓은 시간에 반복적으로 돌아가는 작업이 필요했고, 이런 경우에 배치를 정말 많이 사용했다.
처음 배치를 접했을 때에는 이거 어떻게 짜야하는거지 ............?

싶었지만 실무에서 경험을 해보다보니 어느 정도 배치에 대해서 감이 정말 정말 살짝 생긴 것 같다. (아직 갈 길이 멀다)
마지막으로 배치 개발을 Spring Batch + Scheduler를 통해서 했었는데 생각보다 Spring Batch 가 너무 똑똑하고 개발하기도 편리해서 오늘은 Spring Batch에 대해서 알아보고자 한다.
현재 글인 이론편을 시작으로 실전 편까지 아자잣.
Spring Batch 에 대해서 본격적으로 알기 전에 Batch 에 대해서 먼저 짚고 넘어가자.
Batch 란 ?
정확한 뜻을 먼저 파악하기 위해서 영어 사전에 batch 의 의미에 대해서 찾아보았다.

사전의 뜻을 보았을 때 "일괄적으로, 한번에" 라는 의미로 생각하면 될 것 같다
즉, 배치는 데이터를 실시간으로 처리하는 대신, 일정 기간 동안 데이터를 모아 일괄적으로 처리하는 방식을 의미한다.
이는 대량의 데이터를 효율적으로 처리하거나 특정 시간에 집중적으로 작업을 수행할 때 유용하다.
예를 들어서 어떤 쇼핑몰에서 포인트를 적립하는 기능을 개발한다고 하자
기획 요구사항이 00시마다 자동으로 포인트가 적립되어야 한다.
그러면 포인트 적립 대상자가 되는 회원들을 일괄적으로 모아서 00시마다 처리해줘야 한다.
이렇게 일괄적으로 처리하는 기능이 바로 배치이다.
쉽게 이해하자면 배치 == 일괄처리라고 생각하면 된다.
여기서 중요한게
포인트 적립의 대상자가 되는 회원들을 일괄적으로 처리하는 것과 00 시마다 적립되는 것을 분리해서 생각해야 한다.
일괄적으로 처리하는 것은 => 배치이지만
00 시마다 적립되는 행위 => 스케줄러의 일이다.
그러면 본격적으로 Spring Batch 에 대해서 알아보자
Spring Batch 란?
Spring Batch는 스프링에서 제공하는 강력한 배치 애플리케이션을 개발할 수 있도록 해주는 가볍고 포괄적인 배치 프레임워크다.
배치는 일정 기간 동안 데이터를 모아 일괄적으로 처리하다 보니 보통 대량의 레코드를 많이 처리하곤 한다.
스프링 배치는
1) 로깅 / 추적
2) 트랜잭션 관리
3) 작업 처리 통계
4) 작업 재시작
5) 건너뛰기
6) 리소스 관리 등
대량의 레코드를 처리하는데 필수적인 기능들을 제공한다. 또한 최적화 및 분할 기술을 통해 매우 대량 / 고성능 배치 작업을 가능하게끔 한다.
사용 사례
스프링 배치는 다음과 같은 작업에서 사용된다.
1. 사용자 상호 작용 없이 처리되는 대량의 정보에 대한 자동화되고 복잡한 처리
예시 : 매일밤 저녁마다 오늘 판매한 금액에 대해서 판매자에게 정산해 주기
2. 매우 큰 데이터에 반복적으로 처리되는 복잡한 비즈니스 규칙의 주기적 적응
예시 : 각 상품 별 판매된 통계를 기반으로 예상 판매 수량을 계산하는 경우
3. 포맷팅, 검증 및 트랜잭션 방식으로 처리가 필요한 내부 및 외부 시스템에서 수신한 정보를 기록 시스템에 통합
예시 : 주문 결제 데이터를 가져와서 쇼핑몰의 주문 처리 시스템에 기록하는 경우
제공하는 시나리오
스프링 배치를 사용하라고 제공하는 시나리오는 다음과 같다.
- 주기적으로 일괄 처리를 수행한다.
- 작업의 병렬처리로 동시 일괄 처리를 한다.
- 단계적 엔터프라이즈 메시지 중심 처리
- 대규모 병렬 일괄 처리
- 실패 후 수동 또는 예약된 재시작
- 종속 단계의 순차적 처리
- 부분 처리 : 레코드 건너뛰기 (롤백 시)
- 전체 배치 트랜잭션
위에서 일괄 처리가 총 3번 나오는 걸 알 수 있는데 그렇듯이 스프링 배치를 사용하는 가장 보편적인 이유는 바로 "일괄 처리"다
스프링 배치를 어떤 상황에서 사용하고 왜 사용해야 하는지 이 정도면 감이 왔을 것이라고 생각한다.
그러면 이제 스프링 배치가 어떻게 구성되어 있는지를 알아보자.
스프링 배치 아키텍처
스프링 배치 아키텍처는 다음과 같다.
Application, Batch Core, Batch Infrastructur로 총 3개의 주요한 구조로 되어 있다.
각각 맡은 역할을 수행하며

Application
- 개발자가 작성한 모든 배치 작업 과 사용자 정의 코드
- 비즈니스 / 서비스 로직
Batch Core
- 배치 작업을 시작하고 제어하는 데 필요한 핵심 런타임 클래스가 위치
- Job, Step, JobLauncher
Batch Infrastructure
- 외부와 상호작용
- ItemReader, ItemWriter, RetryTemplate
배치 원칙 및 지침
배치를 구축할 때에는 고려해야할 주요 사항들이 몇 가지 있다.
Spring Batch docs 에 있는 내용 중 가장 핵심적으로 보이는 내용들을 모아 가져왔다.
- 가능한 한 단순화하고 단일 배치 애플리케이션에서 복잡한 논리적 구조를 구축하는 것을 피해라
- 시스템 리소스 사용을 최소화해라. 내부 메모리에서 가능한 한 많은 작업을 수행해라.
- 데이터 무결성과 관련해서 항상 최악의 상황을 가정해라
- 파일 백업 절차를 마련하고 문서화할 뿐 아니라 정기적으로 테스트해라
- 불필요한 물리적 I/O 가 발생하지 않도록 애플리케이션 I/O 를 검토해라. 특히 아래의 네 가지 결함을 찾아야 한다.
- 불필요한 테이블이나 인덱스 스캔이 발생하는 경우
- Where SQL 문의 절에 키 값을 지정하는 경우
- 동일한 트랜잭션에서 이전에 읽은 데이터가 있는 경우
배치 구성 요소
그러면 배치 아키텍처의 구성요소에 대해서 살펴보자 !

간단한 배치 애플리케이션부터 복잡한 배치 애플리케이션까지 사용한다.
구성 요소 및 기술 서비스의 물리적 구현을 제공하며, 매우 복잡한 처리 요구 사항을 해결하기 위한 인프라와 확장 기능을 제공한다.
JobRepository
JobLuancher
Job
Step
ItemReader
ItemProcessor
ItemWriter
Job 에는 1:N 으로 Step 과 연결되며, 각 Step 에는 한개의 ItemReader, ItemProcessor, ItemWirter 를 가지고 있다.
JobLauncher 을 통해서 작업을 시작하며, 현재 실행 중인 프로세스에 대한 메타데이터는 JobRepositoy 에 저장된다.
배치에 대해서 어느 정도 감이 왔을 것이라고 생각한다. 다음은 Spring Batch 를 실제로 어떻게 구성하고 어떻게 사용해야 하는지를 실전편을 통해서 알아보자 !