
단일 서버 스케줄러의 한계를 깨고, 무유실 수평 확장이 가능한 공통 벌크 실행 플랫폼을 설계한 여정
이 아티클은 트래픽과 데이터양 증가로 인해 단일 애플리케이션 안의 배치가 장애 지점으로 변해가는 과정과 극복기를 다룹니다. 분산 락과 멱등성 보장만으로는 해결할 수 없었던 병목 현상을 해결하기 위해 스케줄러를 외부로 격리하고 작업을 안전하게 분배한 실무 가이드를 제공합니다. 대규모 데이터를 유실 없이 병렬 처리하기 위한 상태 기반 복원력 설계 패턴의 핵심을 설명합니다.
스프링의 @Scheduled 배치 처리가 느려져 시스템 다중화를 고민하고 있거나, 복잡한 분산 환경 속에서 영속적인 스케줄 제어와 완벽한 유실 복구를 보장하고자 하는 백엔드 아키텍트들에게 적극 권장합니다.
애플리케이션 내부에 `@Scheduled` 어노테이션을 사용하여 단일 인스턴스 구조로 배치 작업을 돌리던 중, 처리해야 할 데이터 규모가 증가하면서 처리 지연이 발생했습니다. 문제를 해결하고자 애플리케이션의 Pod를 다중화했으나 스케줄러까지 함께 복제되어 동일한 작업이 여러 Pod에서 중복으로 실행되며 시스템 자원이 낭비되는 병목 현상이 발생했습니다.
스케줄링 주기와 실행 로직을 분리하기 위해 트리거를 애플리케이션 외부로 격리하고, 트리거가 울리면 처리할 작업을 공유 저장소에 원자적으로 펼쳐두게 했습니다. 이후 여러 Pod가 공유 저장소에서 자기 몫의 대상을 원자적으로 선점하여 병렬 처리하도록 구조를 개선하였으며, 이를 유실 방지와 상태 재개가 가능한 공통 벌크 실행 플랫폼으로 구축했습니다.
Pod를 유연하게 늘리는 스케일 아웃 방식으로 처리량을 비례하여 증폭시킬 수 있게 되었습니다. 또한 작업 중인 Pod가 예상치 못하게 종료되어도 다른 인스턴스가 하트비트를 감지하고 최종 체크포인트부터 안전하게 작업을 이어받아 중복이나 유실 없는 무중단 처리를 보장하게 되었습니다.
Trade-off
한 줄의 어노테이션으로 간편하게 해결되던 이전 구조에 비해 외부 스케줄러, 원자적 선점을 관리할 공유 저장소, 그리고 상태 추적(체크포인트, 하트비트)을 위한 추가 인프라 도입과 설계상의 아키텍처 복잡성이 크게 상승했습니다.
여러 애플리케이션 인스턴스가 동시에 공통 자원에 접근할 때 데이터의 일관성을 보존하기 위해 외부 저장소(Redis 등)를 활용하여 상호 배제(Mutual Exclusion)를 보장하는 기술입니다.
여러 작업자가 동시에 대상을 선택해 갈 때, 원자적 쓰기 연산을 통해 특정 작업의 소유권을 중복 없이 안정적으로 확보해 오는 분산 데이터 제어 패턴입니다.
작업 처리의 진행 상황(좌표)을 데이터베이스에 실시간으로 기록하고(체크포인팅), 서버의 생존 여부(하트비트)를 모니터링하여 중단된 기점부터 작업을 복구하도록 만드는 신뢰성 설계 패턴입니다.








