CS

배치 개발

soohykim 2025. 6. 27. 16:19
728x90
반응형

✅ 배치 개발

 

🔸 1. 실행 방식과 스케줄링

  • 배치: 주기적으로 실행되는 백그라운드 작업 (예: “매일 새벽 2시에 트랜잭션 집계”)
  • 서비스: 클라이언트 요청에 따라 즉시 실행되는 상호작용형 또는 실시간 처리 시스템
  • 배치는 스케줄러(cron, Airflow) 로 관리하며, 실행 타이밍과 리소스를 사전에 정해야 합니다.

 

🔸 2. 내결함성(Idempotence)과 오류 복구

  • 배치는 실패 시 중복 작업이나 데이터 무결성 훼손 없이 반복 실행 가능해야 합니다
  • 실시간 서비스는 요청 실패 시 재시도 메커니즘이 상대적으로 간단할 수 있음
  • 배치는 실패 시 중단 위치에서 재시작 가능한 구조(Job restart, checkpoint) 이어야 하며, 중복 방지를 위한 키 기반 처리가 필수입니다.

 

🔸 3. 리소스 관리 및 분리

  • 배치는 대량 데이터 처리 시 자원 소모가 크며, 실시간 서비스와는 분리된 환경에서 실행해야 합니다
  • 실시간 서비스는 사용자 요청에 대한 응답 시간 최적화가 주 목표입니다
  • 배치 전용 서버 또는 컨테이너 사용
  • 프로덕션 서비스와 배치가 같은 인스턴스에서 실행되지 않도록 리소스를 분리해야 합니다.

 

🔸 4. 설계 구조 

  • 배치 애플리케이션 구성 요소:
    Job → Step → ItemReader → ItemProcessor → ItemWriter 
  • 서비스: API 엔드포인트 → 비즈니스 로직 → DB 트랜잭션으로 단순 구성
  • 배치는 단계별 Chunk 처리, 병렬 실행, 파티셔닝, 그리고 체크포인트 설계가 핵심입니다.
  • Job은 독립된 모듈로 배포/버전 관리되어야 합니다.

 

🔸 5. 모니터링, 로깅, 운영 대응

  • 배치는 단위 실행 상태, 시작/종료 시간, 처리 건수, 오류 로그 등을 상세히 기록해야 하며
  • 운영 중에는 모니터링 도구(Prometheus, ELK 등)와 알람 시스템을 통해 즉시 장애 감지 및 재실행 대응해야 합니다
  • 배치 전용 로그/메트릭을 정의하고, UI 기반 실행 이력 뷰와 재시작/재처리 기능이 있어야 합니다.

 

🔸 6. 테스트 방식

  • 배치는 대량 데이터를 처리하므로 단위+통합+성능 테스트가 필수입니다
  • 서비스는 주로 단위와 API 테스트 위주
  • 소규모 테스트 데이터로 기능 검증 → 전체 데이터로 성능 테스트
  • 테스트 케이스는 각 Job의 정상/예외/재시작 시나리오 검증이 포함되어야 합니다.

 

실행 스케줄 기반 주기 실행 클라이언트 요청 기반 즉시 처리
오류 복구 재시작, 체크포인트, idempotence 필요 단순 재시도 설계, 중복 방지 적음
리소스 관리 전용 인스턴스/컨테이너, 병렬·파티셔닝 설계 필요 반응 속도/동시성 중심, 리소스 분리 제한
설계 구조 Job‑Step 구조, Chunk 처리, 병렬/파티셔닝 고려 API‑비즈니스‑DB 트랜잭션 구조
모니터링 실행 로그, 메트릭, 오류 추적, 재처리 UI 요청 로그, 실시간 모니터링 중심
테스트 단위+통합+성능 테스트 (대량 데이터 환경 가정) 단위 및 API 테스트 중심
 

 

 

“배치 개발은 대량 처리 작업을 주기적으로 수행해야 한다는 점에서 실시간 서비스와 다릅니다. 배치는 스케줄 관리와 자원 분리가 필수이고, idempotence 설계, 체크포인트 기반 재시작 기능, 병렬/파티셔닝 전략이 중요합니다. 또한 모니터링과 재실행 기능, 성능 테스트를 반드시 포함해야 합니다. 반면 실시간 서비스는 주로 응답 성능과 동시성 최적화에 집중합니다.”

 

“저는 배치 개발 시 먼저 배치 흐름과 실패 처리 시나리오를 설계하고, 스케줄러 기반 Job 설계를 설계 단계에서 명확히 합니다. 구현 시 Spring Batch로 예외 처리와 병렬 파티셔닝을 적용하고, 배포 후에는 Grafana + Prometheus를 통해 실행 상태와 리소스를 모니터링합니다. 또한 오류 발생 시 자동 재시도 및 Dead-Letter 큐 분리 구조를 활용하며, 배치 크기와 스레드 수, 인덱스를 조정해 성능을 최적화하고 있습니다.”

 

 

 

 


✅ 데이터 정합성 유지 방법

🔸 1. ACID 트랜잭션 (Atomicity, Consistency, Isolation, Durability)

  • 단일 DB 내에서 트랜잭션 묶음 수행 → 모두 성공/실패 보장
  • 예: 계좌 이체 시 출금 + 입금 모두 하나의 트랜잭션으로 처리

 

🔸 2. 격리 수준 및 락 관리

  • Dirty Read 등 트랜잭션 간 간섭 방지 위해 적절한 격리 수준 설정 (예: READ COMMITTED 또는 SERIALIZABLE) \
  • 경쟁 조건 많은 테이블엔 SELECT FOR UPDATE로 명시적 락 설정

 

🔸 3. 두-페이즈 커밋(2PC) 또는 보상 트랜잭션

  • 분산 트랜잭션 시 2PC 사용하여 모든 참가 DB가 커밋을 수락할 그때만 실제 commit 수행 
  • 실패 시에는 보상(Compensating Transaction) 로 이전 상태 복구 

 

🔸 4. 체크포인트 & Savepoint (배치)

  • 대량 건 처리 시 중간에 Savepoint 설정 → 부분 실패해도 재시작 가능한 지점 확보

✅ 실패 발생 시 복구/롤백 전략

🔸 배치 처리

  1. 트랜잭션 포함으로 묶음 작업
  2. 예외 발생 시 전체 롤백 후 Savepoint 또는 시작 지점부터 재시작
  3. 실패 데이터는 Dead Letter, 재처리 큐 등으로 분리 
  4. 모니터링 알림: Prometheus/Grafana + 알람 설정

 

🔸 서비스 요청/실시간 처리

  1. 단일 DB에서는 트랜잭션으로 automomic 처리
  2. 분산 환경이라면
    • 2PC 사용하거나
    • Saga 패턴 + 보상 트랜잭션 활용
  3. Idempotency 키로 재시도 시 중복 방지 
  4. Timeout + 롤백 처리로 교착 상태 예방

 

 

“금융 데이터는 정확성과 무결성이 핵심이라 배치든 서비스든 트랜잭션에 대한 통제와 실패 복구를 철저히 합니다.
단일 DB에선 ACID 트랜잭션과 격리 수준 락(READ COMMITTED, SELECT FOR UPDATE)을 지키고, 배치에서는 Savepoint로 중간 복구 지점을 만들며 롤백 시 Dead Letter로 분리합니다.
분산 환경에서는 2PC 또는 Saga 패턴, 보상 트랜잭션, 재시도 시 idempotency 키를 사용해 데이터 일관성을 유지합니다.
테스트와 모니터링도 중요해, 실패 시 알람 + 자동 재실행 구조까지 구축합니다.”

728x90
반응형