콘텐츠로 이동
Exposed 문서1.11

Exposed 배치 유틸리티

최신 안정판 Exposed 1.11.0 릴리스 기준

lease, checkpoint, retry, skip과 JDBC/R2DBC 실행 저장소를 명시적으로 다루는 경량 코루틴 배치 런타임입니다.

BatchStepRunner는 하나의 BatchStep을 재시작 가능한 청크 반복문으로 실행합니다. 잡과 스텝 실행 lease를 획득하고, 이미 COMPLETED 또는 COMPLETED_WITH_SKIPS인 스텝은 건너뜁니다. 실행 대상이면 reader와 writer를 열고 checkpoint를 복원한 뒤 읽기·처리·쓰기·checkpoint 저장을 반복합니다. 이 모듈은 자체 런타임이며 Spring Batch를 감싼 구현이 아닙니다.

BatchStepRunner 실행 흐름

작업을 BatchReader → 선택적 BatchProcessorBatchWriter로 표현할 수 있고 작은 코루틴 배치 런타임이 필요할 때 사용하세요. 프로세스가 종료되어도 재개해야 한다면 영속 JDBC 또는 R2DBC BatchJobRepository를 선택합니다. Spring Batch의 잡 저장소, 스텝 생태계, 파티셔닝, 스케줄링 연동, 운영 도구가 필요하다면 Spring Batch를 사용하세요.

생태계 BOM을 가져오면 모듈 버전을 따로 적지 않아도 됩니다.

dependencies {
implementation(platform("io.github.bluetape4k:bluetape4k-dependencies:<version>"))
implementation("io.github.bluetape4k.exposed:bluetape4k-exposed-batch")
}

잡과 각 스텝에는 상태, 처리 건수, 소유자, lease 만료 시각, 버전, checkpoint가 저장됩니다. 저장소는 소유권을 원자적으로 획득해야 합니다. 획득에 실패하면 스텝 자원을 열지 않고 FAILED 보고서를 반환합니다. 완료된 스텝도 다시 열지 않고 기존 결과를 즉시 반환합니다. 미완료 스텝은 저장된 checkpoint가 있을 때만 첫 읽기 전에 복원합니다.

각 청크에서 processor 예외는 SkipPolicy로 판단합니다. 통과한 출력은 writer에 전달합니다. writer.write()가 성공한 뒤에만 reader.onChunkCommitted()를 호출하고 reader.checkpoint()를 저장하며 write count를 늘립니다. 이 순서가 재시작 의미를 결정합니다.

배치 DSL로 잡과 스텝을 정의하고 reader, writer, 청크 크기, retry 정책, skip 정책, 커밋 제한 시간, 저장소를 제공합니다. 처음에는 SkipPolicy.NONE과 replay에 안전한 writer를 사용하세요. InMemoryBatchJobRepository는 테스트 또는 폐기 가능한 단일 프로세스 실행에만 적합합니다.

Terminal window
./gradlew :bluetape4k-exposed-batch:test

테스트 모음에서 완료 스텝 단축 실행, checkpoint 복원, retry·skip, 취소, JDBC/R2DBC 저장소 영속화를 실행 가능한 계약으로 확인할 수 있습니다.

  • BatchJob, BatchStep 또는 DSL builder로 작업 정의를 만듭니다.
  • BatchReader.open/read/checkpoint/restoreFrom/onChunkCommitted/close를 구현합니다.
  • 입력과 쓰기 출력이 다르거나 항목을 걸러야 할 때 BatchProcessor를 추가합니다.
  • BatchWriter.open/write/close를 구현합니다. write에는 통과한 청크 하나가 전달됩니다.
  • SkipPolicy.NONE, ALL, maxSkips 또는 업무 전용 정책을 선택합니다.
  • 재시작 상태를 영속화하려면 ExposedJdbcBatchJobRepository 또는 ExposedR2dbcBatchJobRepository를 사용합니다.

자연 키, upsert, compare-and-set, 처리 원장으로 writer를 멱등하게 만드세요. reader 정렬을 안정적으로 유지하고 모호하지 않게 재개할 수 있는 상태를 checkpoint에 담습니다. lease 기간은 정상 청크 지연보다 길게 잡고 retry 횟수에는 상한을 둡니다. processor의 항목 skip과 writer의 청크 skip은 업무 의미가 다릅니다. writer retry가 소진되면 청크 전체가 skip 대상입니다.

ExposedJdbcBatchJobRepository는 잡, 스텝, lease, 처리 건수, 상태, checkpoint를 Exposed JDBC로 저장합니다. ExposedR2dbcBatchJobRepository는 같은 역할을 suspend 가능한 R2DBC 방식으로 제공합니다. 방식에 맞는 JDBC/R2DBC reader와 writer도 있습니다. 이 저장소는 경량 런타임 전용이며 Spring Batch 메타데이터 스키마나 트랜잭션 규칙과 별개입니다.

데이터베이스 문장 제한, 행 크기, 측정한 트랜잭션 지연을 바탕으로 청크 크기를 정합니다. retry 횟수, 최초 대기 시간, backoff 배수, 최대 대기 시간, skip 정책, 커밋 제한 시간, lease 만료를 의도적으로 설정하세요. 영속 저장소를 사용하기 전에 배치 테이블을 만들고, JDBC Database 또는 R2DBC R2dbcDatabase와 커넥션 풀은 애플리케이션이 제공하고 소유합니다.

  • 다른 소유자가 유효한 lease를 가지고 있음: 소유권 획득에 실패하며 runner는 스텝을 처리하면 안 됩니다.
  • 쓰기는 성공했지만 checkpoint 저장 전에 프로세스가 종료됨: 재시작할 때 같은 청크가 다시 실행될 수 있습니다.
  • 시간 초과된 쓰기가 외부에 일부 반영됨: 시간 초과만으로 롤백을 단정하지 말고 retry 전에 정합성을 확인합니다.
  • writer retry가 소진되고 skip 정책이 허용함: 청크 전체가 skipCount에 더해지므로 이 범위를 고려해 정책을 정합니다.
  • checkpoint가 없음: restoreFrom을 호출하지 않고 reader의 최초 위치에서 시작합니다.

잡·스텝 ID, 소유자와 lease 만료, 상태, checkpoint, 읽기·쓰기·skip 건수, retry 횟수, 청크 지연, 시간 초과 오류를 기록하세요. 만료된 RUNNING lease와 반복되는 FAILED·STOPPED 복구에 경고를 겁니다. replay와 일부 부수 효과를 진단할 수 있을 만큼 실행 이력을 보존하세요.

./gradlew :bluetape4k-exposed-batch:test를 실행합니다. 자원을 열지 않는 완료 스텝 단축 실행, checkpoint 유무에 따른 동작, processor skip, writer retry·backoff, retry 소진 뒤 청크 skip, lease 경쟁, 쓰기 시간 초과, 쓰기 뒤 checkpoint 전 장애, JDBC/R2DBC 저장소 재시작을 검증하세요.

취소는 별도로 단언해야 합니다. CancellationException은 일반 실패로 바꾸지 않습니다. runner는 NonCancellable 정리 구간에서 STOPPED 보고서 저장을 시도하고 reader와 writer를 각각 닫은 뒤 취소를 다시 던집니다.

트랜잭션 경계를 읽은 뒤 Spring Boot Batch 연동과 실행 모델을 비교하세요. 사용자 정의 reader나 writer를 만들기 전에 영속 저장소 테스트를 재시작 계약으로 삼는 것이 좋습니다.

쓰기와 checkpoint 사이의 경계는 at-least-once이며 exactly-once가 아닙니다. InMemoryBatchJobRepository는 재시작 상태를 영속화하지 않고 여러 프로세스를 조정할 수도 없습니다. 이 런타임은 스케줄러, 큐, Spring Batch 대체재가 아닙니다. 올바른 복구에는 원자적 lease 구현, 영속 checkpoint, 안정된 reader 정렬, 멱등 writer가 필요합니다.

아래 그림은 1.11.0 배포본의 README 자산을 해당 배포 커밋에서 직접 불러옵니다. 이후 SNAPSHOT이 아니라 이 매뉴얼 버전의 구조와 실행 흐름을 보여 줍니다. 미리보기를 누르면 같은 배포 커밋의 SVG 원본이 열립니다.

Batch benchmark comparison 지도

배포본 README: utils/batch/benchmark/README.ko.md

Batch 런타임 role 지도

배포본 README: utils/batch/README.ko.md

Batch chunk checkpoint 흐름

배포본 README: utils/batch/README.ko.md