[개발지식] Web Application의 상호보완적 Eventually Consistency #1 - Batch/Spring Batch의 본질적인 이해

Hyo Kyun Lee·2025년 10월 24일
0

개발지식

목록 보기
94/100

1. 개요

지금까지 배우고 경험하였던 개발항목들은 모두 Web Application에 대한 내용으로, 실무적으로 해결해야하는 문제상황에 대해 고민하고 개선하면서, 나아가 이에 대해 깊게 알아보고 공부하면서 체득하였던 내용들이다.

그렇기에 배치라는 것을 단순하게, Web Application을 공부하고 실무적으로 다루다보면 자연스럽게 익힐 수 있는 "하나의 작은 영역이지 않을까"라는 생각을 가지고 있었는데, 더 공부하고 알아보니 전혀 아니었다.

오히려 별도의 영역으로 보아야 하는 큰 영역이고, 두 영역의 본질적인 개념이 아예 다른 독립적인 개념이자 서로 상호보완적인 관계에 있는 개념이라는 것을 알게 되었다.

지금부터 Batch/Spring Batch부터 시작해서, 이를 실무에 즉시 활용할 수준으로 깊게 알아볼 예정이며 이에 대해 공부하고 구현한 내용들을 기록해보고자 한다.

그 시작은 Batch/Spring Batch의 본질적인 개념 부터 시작해보겠다.

2. 배치란 무엇인가

일단 Spring batch를 다루기 위해선, 먼저 batch란 무엇인가, 어디에 쓰이는가 등 정확한 목적과 개념에 대해 먼저 알 필요가 있다.

결론부터,

배치처리란, 대량의 데이터를 동시에, 정해진 시간에(특정 시간에 특정 단위로) 일괄적으로 처리하고 결과를 출력하고 확인하는 작업을 말한다.

즉, 개발자들이 자리를 비운 사이에 시스템이 자동으로, 효율적으로 데이터를 처리하는 시스템이다.

예를 들어, 매일 새벽 4시에 은행이 서버점검시간에 이전의 거래 데이터를 집계하거나, 인기상품 선정을 위해 상품거래데이터를 분석하거나, 컴플라이언스 시스템을 통해 부당거래유무 등 의심 패턴을 확인하는 등의 작업을 진행하는 것이다.

배치처리의 기본적인 출발점은 "이 작업을 사람이 직접 할 수 있는가?"에서 시작하며, 쉽게 말하면 특정 시간에 컴퓨터가 효율적으로/일괄적으로 처리하여 그 결과를 보고하는 과정이다.

3. 대용량 처리를 해야하는가 - 배치의 필요조건

배치처리를 할 때 대용량 처리를 무조건적으로 진행하는 것은 아니다. 다만, 배치처리의 "특성 상" 보통은 대용량 데이터를 처리하는 것이다.

이처럼 배치처리를 설계하기 위해선 사소한 요소들 하나하나 살펴보고 고민을 해야한다.

배치처리를 설계할 때 기본적으로 갖추어야할 필요조건이자, Web Application과 상호보완적인 배치시스템을 구축하기 위한 조건들, 즉 배치처리의 목적과 개념에 부합하는 조건들이 있을지 한번 고민해보고 살펴보아야 한다.

  • 대용량 데이터 처리
    배치는 대량의 데이터를 효율적으로 처리한다. Web Application이 특정 ID의 데이터 하나를 조회하거나 수정한다면, 배치는 수천~수만개의 데이터를 효율적으로 한번에(일괄적으로) 처리한다.

  • 정기적 실행
    배치는 매일 혹은 매주 혹은 매달 정해진 특정 시간에 실행된다. 배치와 스케쥴러는 다른 이야기이다. 다만, 배치 처리를 위해 스케쥴러가 보통은 반드시 필요하고, 이로 인해 스케쥴러가 대중화된 이유이다.

  • 무인처리
    사람이 하지 못하는 작업을 보통 새벽시간에 대신 처리해준다.

  • 유한한 양의 데이터 처리
    배치는 정해진 양의 데이터만 처리한다. 처리할 대상이 명확하게 정해져 있기에 결과를 정확하게 예측할 수 있다.

  • 예측가능한 부하 처리
    배치는 시스템의 처리 능력에 맞게 설계된다. 시스템이 감당가능할 수 있는 수준만큼의 부하를 설계하고 구축해야 하며, 이를 처리할 수 있는 인프라(CPU/SSU/메모리)가 적절하게 있어야 한다.

  • 복구 가능성 / 재처리성 (Idempotent & Restartable)
    대량 데이터 처리 도중 실패 시, 중단점부터 복구(restart) 가능해야 한다. 또한 중복 실행 시 결과가 일관되게 유지되어야(Idempotent) 하며, 배치 프레임워크(Spring Batch 등)은 이 부분을 핵심적으로 보장한다.

배치처리와 헷갈릴 만한 개념들을(대용량 처리와 스케쥴러) 간단하게 정리해보았다.

구분핵심 목적수행 시점처리 단위대표 예시
배치 처리 (Batch Processing)대량의 데이터를 묶어서 일괄 처리주기적 / 비실시간파일, DB 데이터, 집계 단위 등매일 0시에 매출 집계, 월말 정산
대용량 처리 (Large-scale Processing)처리량(throughput) 자체가 많음실시간 또는 배치 모두 가능데이터 스트림, 로그 등대용량 로그 분석, 빅데이터 파이프라인
스케줄러 (Scheduler)배치를 실행시키는 ‘시간 관리 도구’주기 또는 이벤트 기반실행 트리거cron, Spring Scheduler, Airflow 등

3-1. Scheduler와 Batch의 차이점

더 세부적으로 알아보겠다.

"스케쥴링" 처리와 "배치" 처리를 정확하게 구분이 가능해야 배치 필요성을 느끼고, 적절한 배치처리를 설계할 수 있지 않을까?

단계적으로 살펴보자.

배치처리를 하기 위해 스케줄러가 반드시 필요한 필요조건은 아니지만, 대부분 거의 함께 쓰인다.

배치(batch)는 “비실시간 + 일괄 처리”라는 특성을 가지는 처리 방식이며, “언제 실행되느냐”보다는 “어떻게 데이터를 처리하느냐”, 즉 세부 로직이 중점사항이다.

반면 스케줄러(scheduler)는 “언제, 어떤 주기로 배치를 실행시킬 것인가”를 관리하는 도구, 개별적으로 본다면 "언제 실행하는가"에 대해 관심을 가지는 하나의 시간적 관리 체계라 할 수 있겠다.

참고로 배치는 스케줄러 없이도 수동으로 실행할 수 있기에, Batch = Spring Batch라 보는것은 곤란하고, 진입점만 있다면 단독으로 실행가능한 또 하나의 처리 체계라 보면 되겠다.

아직도 헷갈린다면, 더 세부적으로 살펴보겠다.

스케줄링된 작업 중에서 “데이터를 일괄적으로 처리하는 로직”을 가진 것만이 진짜 배치다.

즉,

“스케줄링은 실행의 트리거(언제)”
“배치는 처리의 형태(어떻게)”

이 차이가 본질이다.

스케쥴링 처리는 "언제" 처리가 쟁점이고, 무엇을 처리하는지는 중요하지 않다. 중요하더라도, "무엇을 처리하는지"보다 "언제 처리하는지"가 더 중요하다.

반면에 배처 처리는 "어떤 명확한 목적을 가지고 어떠한 과정을 거쳐 일괄적인 처리를 하는지"가 중요하다. 즉, "무엇을 처리하느냐"가 더 중요하다.

예를 들어, 단순 이메일을 보내는 것은 배치처리보다는 스케쥴링 처리에 가깝겠지만, 당일의 거래로그를 분석하고 이 통계를 바탕으로 컴플라이언스 결과를 도출하는 과정은 배치 처리에 가깝겠다.

여기서 마지막으로, 배치처리가 단순 처리일 수 있을텐데, 이 경우 스케쥴링 처리와 어떻게 구분할 수 있는가까지 의문이 들 수 있다.

로직이 ‘일괄 처리(batch)’와 '결과 저장 및 보고', '명확한 업무목적'의 성질을 지닌다.

그리고,

“처리의 연속성”이나 “데이터 일관성 복구 책임”을 가진다.

이 특성이 보인다면 단순 처리성 배치이다.

특히, 단순 호출 스케쥴링 처리에서 실패시 재시도에 대한 로직이 추가된다 하더라도, 단순 안정적인 운영을 위한 부수적인 조치일 뿐 이 이상의 결과 추출 및 활용 등의 조치가 전혀 없기 때문에 여전히 스케쥴링 처리라 봐야 한다.

다시 정리하면, 단순로직처리(“데이터 I/O가 없는 배치”, 즉 순수한 계산/업무성 로직만 수행하는 배치, 보통 데이터 클렌징이나 캐시갱신 등의 업데이트 성격의 작업들)라도 일괄성과 결과저장/보고성의 특징이 있다면, 이는 배치처리라 할 수 있겠다.

특히 로직 형태 (처리 구조)는,
데이터를 읽고(Read) → 처리하고(Process) → 저장(Write)하는 구조로 되어있다(보통). 단순 처리라 할지라도 결과를 저장하고 보고하는 목적의 로직이 포함되어있다.

위에서 잠깐 언급하였지만, 이런 분류의 task성 배치처리는

  • 캐시 갱신
  • 로그 압축/삭제
  • 파일 이동/백업
  • 관리자 알림 메일 전송

등의 작업들을 그 예로 볼 수 있겠다.

캐시 갱신과 캐시 클리어, 이 두 작업 중 어느 것이 스케쥴링 작업이고 배치 작업인지 구분할 수 있는가?

구분예시목적성격분류
캐시 클리어 (Cache Clear)매시간 Redis 캐시 flush서버 메모리/성능 관리, 환경 초기화운영성 관리 작업스케줄링
캐시 갱신 (Cache Refresh / Warm-up)매일 새벽 4시 DB 데이터를 조회해 캐시에 갱신향후 트래픽 대비, 데이터 미리 로드업무 데이터 기반 일괄 처리배치 처리

운영적 안정성을 위해 캐시를 비우는 행위는 말 그대로 "비우는 행위", 이 비우는 행위는 비우는 행위 그 자체보다는 언제 이를 처리할 것인지가 더 중요하기에 단순 스케쥴링 처리이다.

하지만 비즈니스 데이터를 읽고 가공하고 처리하는 작업, 이후 갱신 실패 시 데이터를 추적하는 작업까지 이루어지는 등 캐시 갱신의 작업은 명확한 배치 처리이다.

따라서, "위의 명확한 업무목적을 가지는 처리"라 한다면, "이 처리가 비즈니스 데이터를 읽고 가공하는 처리를 진행하는가"부터 찬찬히 파악하면 스케쥴링과 배치처리를 구분하는데 많은 도움이 될 것이다.

이쯤하면 스케쥴링 처리와 배치 처리는 명확하게 구분이 가능할 것이다.

아래와 같이 최종적으로 정리해보았다.

비교 항목단순 스케줄링 작업단순 로직 배치
관심사“시간 기반으로 실행” 자체“비실시간 일괄 처리 로직” 자체
주요 목적단순 호출 자동화특정 업무를 주기적으로 백엔드에서 처리
실행 주체스케줄러가 직접 트리거배치 프레임워크/배치 엔진이 Job 단위로 실행
구조적 특징독립 로직 없음, 단순 메서드 실행배치 단위(Job/Step)로 분리 가능
예시5분마다 헬스체크 API 호출매일 자정 로그 정리, 캐시 갱신 등
에러 처리/복구단순 재시작상태 기반, 재시도, 로깅, 실패 지점 재시작 고려

3-2. Spring Batch와 H2 Database 관계에 대한 오해

또한, Spring Batch와 H2 database의 연관관계에 대해 헷갈릴 수 있다(Spring batch 예제를 검색하면 대부분은 H2와 연결하여 Job/Step 메타데이터를 관리하는 예시를 보여주기 때문).

결론부터 말하자면, RDBMS와 연관이 깊은거지, H2와 연관이 깊은 것은 아니다(하나의 옵션은 될 수 있겠다).

Spring batch의 job repository와 execution context은 각각 job의 실행 및 종료지점, 실행 도중의 정보나 시간 등의 상태 메타데이터를 저장하는데, 이를 h2 in memory db에 저장한다.

그러나 실제 실무에서는 상태정보를 안정적으로 저장하고 그 단계를 추적할 수 있어야 하기에 안정적인 RDBMS에 저장하는 것이 더 일반적이다.

즉,

Spring Batch의 JobRepository와 ExecutionContext는 Job과 Step 실행 상태, 메타데이터를 저장하며, H2 in-memory DB와 같은 RDBMS에도 저장할 수 있다. 단, 메모리 DB는 서버 종료 시 데이터가 사라진다.

참고로, 상태데이터를 저장하는 컴포넌트는 아래 두가지이므로 명확하게 이해하는 것이 중요하겠다.

  • Job Repository

Spring Batch에서 Job과 Step의 실행 정보, 상태, 메타데이터를 저장하는 핵심 컴포넌트이다.

JobInstance, JobExecution, StepExecution, JobParameters 등 배치가 재시작 가능하게 하고, 실행 상태를 추적하며, 실패 복구 등을 가능하게 하는데, 반드시 RDBMS에 저장하도록 설계되어있다.

H2, MySQL, PostgreSQL 등 어떤 RDBMS도 가능하며, 당연하게도 메모리 전용 DB(H2 in-memory)도 설정하면, 서버가 종료되면 정보는 사라진다.

  • Execution Context

Job이나 Step의 실행 상태 데이터를 Key-Value 형태로 저장하여, 현재 처리한 데이터 위치, 커스텀 변수 등을 최종적으로 JobRepository를 통해 RDBMS에 저장한다.

3-2. Batch는 Web Application과 다른 환경(JVM Instance)에서 동작한다.

마지막으로 중요한 점은 Batch는 Web Application과 완벽하게 분리해야 하는 체계라는 점, Application 실행을 하는 것도 Web Application을 통해 단순히 "실행지점, entry point"를 제공해주는 것일 뿐이라는 점을 명확하게 인지해야 한다.

JVM 종료 = 배치 프로그램 종료

JVM(Java Virtual Machine)은 자바 프로그램이 실행되는 가상 머신을 한다. Spring Batch 배치 프로그램도 결국 JVM 위에서 실행되는 자바 애플리케이션의 한 형태이자 독립적인 체계이기에 배치 프로그램을 종료하면 JVM도 종료된다..

다른 애플리케이션의 JVM 종료와는 별개

같은 서버에서 Web application과 batch가 동시에 돌아가더라도, 각 애플리케이션은 독립적인 JVM 인스턴스에서 실행된다.
VM 내부 메모리에만 존재합니다.

따라서, A 배치프로그램에서 H2 in-memory DB를 만들었으면, B 배치프로그램에서느 접근 불가하며, JVM이 종료되면 해당 인스턴스의 in-memory DB도 사라진다.

아래 실행 도식도를 보면 배치와 Web application이 얼마나 독립적인 영역인지 한눈에 들어온다(참고로, Spring Batch는 통신이 아니므로 WAS가 필요없다).

서버 OS
├── JVM #1 : Tomcat(WAS)
│ ├── webapp1
│ └── webapp2
├── JVM #2 : spring-batch.jar
└── JVM #3 : kafka-consumer.jar

다만, 진입점이 Web application 실행을 전제로 한다면 다르다.

이 말은 즉슨, Spring Batch의 처리를 스케쥴러 기반으로 한다면 이는 Web Application과의 상호작용이 필요하다는 의미이다.

이럴 경우 Web Application과 동일한 JVM 메모리, H2 Database도 동일한 메모리를 공유한다.

[WAS / Spring Boot Application JVM]
 ├── Controller
 ├── Service
 ├── Repository
 └── Scheduler (@Scheduled, Spring Task)

즉, 동일한 WAS, 동일한 JVM, 동일한 프로세스, 단지 Spring이 내부적으로 스레드를 하나 더 띄워서 일정 주기로 Job을 호출하는 구조이다.

다만 이 경우라도, SpringBatch와 Web Application은 진입점을 제공하는 관계일 뿐, 본질적인 개념 상 분리해서 이해하는 것이 좋다.

이 외의 경우엔 외부 진입점(외부 스케쥴러)을 사용하여 처리한다.

[Scheduler Server / Process]   ←→   [WAS (Spring Application JVM)]

외부 스케줄러 (Quartz Cluster, Jenkins, Crontab 등)를 사용하는 경우가 이 경우이고 Batch를 바라볼때는 이 관점을 생각하는 것이 이해하기에 편하다. Quartz, Jenkins, Crontab 같은 시스템이 대표적인 예이며, 아예 다른 프로세스(즉, 다른 JVM 또는 OS 레벨 프로세스)로 동작한다는 점을 기억하자.

4. 실무 배치 사례

배치처리를 실무에서 어떻게 활용하고 있는지 살펴보면, 배치처리를 이해하는데 조금 더 수월할 수 있다.

  • 일일 정산 배치 : 하루 동안의 거래 내역, 결제 정보, 사용자 활동 로그를 모두 정리하고 집계한다.
  • 대용량 데이터 마이그레이션 : 시스템 업그레이드나 DB변경 시 해당 시스템 및 DBMS에 맞게 데이터를 정제하는 작업이다. 데이터 규모가 작을 경우 사람의 손으로 이루어질 수도 있으나, 보통은 데이터 규모가 크기에 배치처리에 맡긴다.
  • 레포트 생성 : 하루 동안 집계한 데이터를 기반으로 보고서를 추출하거나, 이메일/알림 메시지를 보내는 작업이다.
  • 데이터 정제 : 보통 데이터 클렌징이라 많이 하는데, 중복 데이터를 제거하고 잘못된 데이터 형태를 바로 맞추는 작업이다. 오래된 데이터나 부정확한 데이터를 정리하여 시스템 신뢰성과 성능을 높일 수 있다.
  • 백업 : 정기적으로 데이터를 분산하여 시스템 장애로 인해 발생하는 데이터 유실을 방지하기 위한 저장 작업이다.
  • 데이터 통합 : 여러 목적으로 분산해있는 데이터를 한 목적의 데이터로 통합하고, 최종적으로 목적에 맞는 최신 데이터로 정합하는 과정이다.

5. 배치는 Web Application과 본질적으로 다른 영역이면서 상호보완적이다.

일단 배치처리를 이해하기 위해선, 이 "영역"이 Web Application과 명확하게 다른 체계라는 것을 인지해야 한다. 배치처리를 자세하게 살펴보는 것은 이 이후이다.

  • Web Application(Interactive) : 사용자 요청에 보통은 즉각 반응하는 실시간 체계이다. 또한 각 요청에 대해 응답할 수 있는 API 체계를 만들어놓는다. 스케쥴링 처리를 통해 실시간 응답을 처리하지 않을 수 있겠지만, 보통은 실시간 응답(속도)을 중요시한다.

  • Batch(Non-Interactive) : 사용자 요청을 기다리지 않는다. 정확하게 말하면 사용자의 요청보다는 특정 목적으로 설계한 비즈니스적으로 필요한 데이터를 추출하기 위해 정해진 시간에 일괄적으로 작업을 실행한다. 결과의 빠른 추출보다는 안전하게, 명확하게 결과를 추출해내는 것이 더 중요하다(Eventually Consistency).

그리고 중요한 것은 오류 처리에 대한 차이이다.

  • Web Application : 잘못된 요청이 오거나 시스템 장애가 발생할 경우, 에러 코드를 반환하고 과정을 바로 종료한다.

  • Batch : 시스템 장애로 인해 배치 작업 도중에 중단점이 발생한다면 재시도하고, 실패를 반복하면 중단하여 이를 기록해놓는다. 실패한 작업을 재시도하고, 도중에 유실이 발생할 경우를 대비하여 복구를 시도한다는 점이 가장 큰 차이점이기도 하다.

따라서, 위 개념으로 알 수 있듯이 Web Application과 Batch는 완전히 다른 세계이다. Web Application이 사용자와 가장 가까이 맞닥뜨리는 최전방이라고 한다면, Batch는 그 최후방에서 안전하고 명확하게 대용량 데이터를 처리하고 집계하는 최후방 체계라 할 수 있겠다.

하지만 이렇게나 다른 두 세계는 서로에게 반드시 필요하고 없어서는 안될 상호보완적인 관계에 있다. 두 시스템이 견고하고 온전히 구축되어 있을때 비로소 안정적인 시스템 체계가 잡혀있다고 볼 수 있겠다.

6. Spring Batch의 필요성

Spring Batch에 대해 이해하고 다루는 것은 Batch의 개념에 대해 이해한 그 다음의 이야기이다.

Batch를 다루기 위해 Spring Batch를 다루는 것이 아니라, Batch 처리의 필요성을 이해하고 이를 효과적으로 다루기 위해 Spring Batch라는 프레임워크를 활용하는 방향으로 접근하는 것이 맞다.

Spring Batch는 배치처리를 효율적으로 진행하기 위한 프레임워크, 즉 도구이다. 따라서 배치처리를 위한 강력한 기능들을 지원한다.

  • 유지보수 : 배치코드는 Web Application의 API와는 달리, 사용자보다는 특정 목적의 설계 목적으로 진행되어 변경점이 자주 발생하지는 않는다. 그만큼 오래 가는 로직이기에 한번 만들때 신중해야 한다.

  • 의존성 주입 : 프레임워크의 생명주기에 배치처리의 의존성, 즉 배치빈을 주입하여 결합도를 낮추고 개발자의 피로도를 줄인다.

  • AOP : 배치를 공통 관심사로 두고 이를 Web Application의 로직과 완전하게 분리, 독립적인 영역으로 관리할 수 있도록 한다(MSA에서 모듈화를 극대화할 수 있다).

  • 추상화 : 배치처리의 패턴들을 추상화한 기능들을 제공하여, 특정 기술/체계에 종속하지 않은 컴포넌트를 제공한다.

참고로, 배치처리의 패턴은 우리가 많이 들어보았을 단어들과 매핑할 수 있다.

  • Job : 하나의 기능, 하나의 목적으로 설계한 배치처리 작업(작업단위, 작업 그 자체)
  • Step : Job을 수행하기 위해 필요한 세부적인 실행 절차(실행단위)
  • ItemReader : 데이터를 읽어오는 컴포넌트
  • ItemProcessor : 데이터를 가공하는 컴포넌트
  • ItemWriter : 데이터를 저장하는 컴포넌트

이렇듯 그만큼 어렵고 복잡한 체계를 기술종속없이, 유연하고 효율적으로 구축할 수 있도록 도와주고 유지보수성을 높인 도구가 바로 Spring Batch라 할 수 있겠다.

특히, 데이터 소스를 읽어오는 ItemReader와 이를 저장하는 ItemWriter의 구현체를 사용하기에, 데이터 처리 로직을 직접 작성할 필요없이 마치 JPA처럼 이를 위해 제공한 구현체 설정 및 사용만으로 원하는 배치 목적을 달성할 수 있겠다.

CSV/TXT, XML/JSON, RDBMS, NoSQL, Messaging 등 처리해야할 데이터나 이기종 시스템은 수없이 많지만, 이에 대해 종속하지 않고 추상화하여 동일한 방식으로 처리할 수 있는 방안을 제공하는 것이 Spring Batch이다.

또한 긴 배치 작업 중간에 저장 지점을 설정하는 체크포인트, 처리할 데이터 양과 특성에 따라 트랜잭션 범위를 조절하거나 커밋 단위를 적절하게 분할하여 트랜잭션을 유연하게 설정하는 등 트랜잭션을 안전하게 관리할 수 있는 방안도 제공한다.

나아가, 각 트랜잭션 요소요소를 세밀하게 제어할 수 있는 기능까지도 제공한다.

  • 재시작 : 배치처리 작업을 진행하면서 실패해도 처음부터 다시 시작할 필요없이, 중단 지점부터(마지막 처리 항목) 작업을 재개한다.
  • 유연한 실행 제어 : 특정 Step만을 선택적으로(매개변수 등을 통해 동적으로) 실행제어가 가능하며, 조건에 따른 조건부 실행까지 제어할 수 있다(이전 Step의 결과에 따른 분기별 Step 처리 등).
  • 추적 : 모든 Job / Step의 실행 상태를 메타 데이터로 관리하여, 작업의 실행 시점과 결과를 세세하게 추적 가능하다.

6-1. Job/Step은 Spring Batch의 핵심 기능이다.

Spring Batch를 다루기 위해 필요한 핵심적인 컴포넌트들을 먼저 파악해보는 것이 좋겠다.

  • Job

배치처리를 설계하는 처리단위이자 업무단위라 할 수 있다. 일전에 언급한 일일 거래로그 및 사용자 거래행위 분석, 데이터 통합 처리 등의 과정은 모두 각각의 Job으로 설계할 수 있다.

  • Step

위에서 구성한 Job들을 처리하기 위해 세부적으로, 단계적으로 나눈 실행 단위이다. 보통은 ItemReader로 데이터 소스를 읽고, ItemProcessor로 데이터를 필터링하거나 처리하여 그 결과를 ItemWriter로 저장하는 단계로 이루어진다.

1개의 Job은 1개 이상의 Step으로 이루어져 있고, Job을 성공적으로 완료했다는 것은 모든 Step을 온전히, 정상적으로 완료했다는 의미이다.

7. 배치처리는 완벽하게 독립적이고 다른 영역이다 - 배치처리만을 위해 Spring Batch에서 제공하는 강력한 기능들

나아가, 스프링 배치는 대용량 데이터를 효율적으로, 안전하게 처리하기 위한 아주 특별한 기능들을 제공해준다.

  • Chunk 지향 처리 : 대용량 데이터를 특정 단위로 잘게 나누어 처리할 수 있도록 지정된 크기(덩어리) 단위인 Chunk를 제공하여 준다. 한번에 처리할 수 있는 데이터양을 제한하여 성능/메모리 사용의 최적화를 가능하게 해준다.
  • 페이징 처리(일정 크기만큼의 데이터를 조회하여 처리) 혹은 커서 처리(데이터베이스 커서를 활용하여 효율적인 데이터 스트리밍을 도와준다) 등의 처리 방식을 지원한다.
  • 하나의 Step을 여러 스레드로 처리하거나(멀티스레드 Step), 여러 Step을 동시에 실행하거나(병렬 Step), 여러 인스턴스에서 배치처리를 분산하여 실행하는 등(분산처리)의 확장성 기법을 제공하여 준다(Scalability Tech).

또한, 아예 별도로 배치처리를 위한 테스트 환경 및 기능들을 제공하기도 한다.

  • 배치전용 테스트 도구 : 배치작업의 실행과 결과를 쉽게 검증할 수 있는 도구 및 테스트 환경을 제공한다.
  • 테스트 지원 : Spring에서 사용하는 테스트 도구들을 Spring Batch 테스트에서도 그대로 활용할 수 있도록 지원하며, 이 환경 역시 독립적이다.
  • 단위 테스트 가능 : 배치 작업을 단위 테스트할 수 있다.

7-1. Spring Batch에서 제공하는 환경과 컴포넌트

Spring Batch 프레임워크에서 제공하는 배치 환경은 결국,

  • Batch Job을 "만들기 위한", 즉 Job을 실행할 환경을 구성하기 위해 필요한 컴포넌트와 실행 흐름(뼈대)을 제공한 환경과 같다.
  • 나아가, 개발자는 직접 구현이 필요한 부분을 적절히 구현하고 이를 프레임워크의 뼈대위에 올려놓음으로써, 비로소 온전한 Spring Batch 동작을 실행할 수 있다.

그렇기에, 프레임워크의 컴포넌트와 개발자 구현 영역을 어느 정도는 이해하고 Spring Batch를 다루는 것이 좋다.

  • Spring Batch Components
  1. Spring Batch는 기본적으로 Job, Step 컴포넌트를 제공해준다.
  2. Job을 실행하고 실행에 필요한 매개변수들을 전달하기 위해 JobLauncher를 제공하며, 말그대로 Batch의 시작점이라 할 수 있겠다.
  3. JobRepository를 통해 Batch에서 실행하는 모든 데이터의 메타데이터를 저장하고 관리하며, Job/Step의 실행정보나 시작 및 종료시점에서의 시간, 상태, 결과 등을 기록하고 저장한다. 말 그대로 상태를 저장하는 곳이며 이 정보들은 Batch 작업의 모니터링 및 문제 발생 시 복구 로직 등에 사용한다.
  4. ExecutionContext를 통해 Batch 실행 도중의 Job/Step 상태 정보를 저장한다. key-value 형태로 담는 객체임, Job/Step 간의 데이터 공유와 Job 재시작 시 상태 복원/체크포인트를 위해 활용한다.
  5. 데이터 처리를 위해 ItemReader/Writer 등의 구현체를 제공하며, 특정 이기종 시스템에 대한 기술적 종속없이 추상화한 공통 구현체를 지원한다.
  • Developers
  1. Configuration을 활용하여, Job/Step의 설계 및 구성을 알맞게 지정하여 Batch 흐름을 정의하고 조절한다.
  2. 각 Step의 실행순서 및 조건을 정의하고, 이를 Spring Bean으로 등록하여 Spring Batch가 이를 인식하고 사용할 수 있도록 구성해준다.
  3. DI를 활용하여, ItemReader/ItemProcessor/ItemWriter 등의 필요 컴포넌트들을 적절하게 사용하고 조합하여 최종적인 Batch 플로우 및 실행 과정을 구성한다.

즉, Step과 Job을 정의하고 이를 빈에 등록하여 Batch 흐름을 설계하고 정의하여, Batch 프레임워크 뼈대 위에 올려주는 것이 개발자의 역할이다.

추가적으로, 데이터 처리 컴포넌트 구현체 사용 시 파일 포맷이나 SQL 쿼리 조건의 세부적인 항목들은 개발자의 몫이며, 파싱 및 데이터 매핑 등의 작업도 별도로 해주어야한다. 또한 캐싱처리 및 알림발송 등의 단순 데이터 처리에 대한 역할은 개발자의 몫이며, Batch 프레임워크는 이에 대한 컴포넌트, 뼈대, 즉 하나의 처리포인트를 제공해줄 뿐이다.

더불어, ItemReader/ItemWriter 구현체가 모든 이기종 시스템을 커버하지는 않기에 상황에 따라 데이터 처리 컴포넌트를 개발자가 직접 구현해야 할 수 있겠다. 또한 Processor와 같은 데이터 필터링은 오롯이 개발자가 필요 조건 및 로직을 알맞게 구성해주어야 한다.

8. 결론

이처럼 Web Application과 별개의 환경이지만, 철저하게 이에 맞는 환경과 도구들을 제공하여 Spring 프레임워크에 익숙한 체계로 배치를 구축하고 유지관리할 수 있도록 도움을 준다.

지금까지 Batch와 Spring Batch를 순차적으로 이해하고 그 필요성을 느껴보았다면, 이제부터는 본격적으로 이 Spring Batch를 통해 배치시스템을 설계하고 구축해보는 단계로 넘어가보면 좋을 것이다.

추가적으로, Batch와 Scheduling(굳이 말하면 단순 반복문)을 철저하게 나눈다기 보다는, 스케쥴링처리를 batch처럼 체계화/구조화하여 "Batch화"할 수 있다고 보는 것이 좋겠다.

즉, 단순 작업처리는 언제든지 batch 작업으로 변환할 수 있으나, 본질적으로는 다른 개념이다.

0개의 댓글