백엔드
수억 건의 데이터, 맛있게 쪼개 먹는 방법 (with. Partitioning)
두줄요약
Spring Batch Partitioning, Cursor Reader, Bulk Operations로 수억 건 데이터 처리의 OOM 문제를 해결했습니다. 병렬 분할과 스트리밍 읽기, 일괄 쓰기 최적화로 성능과 안정성을 함께 높였습니다.
문제 상황
- 원장 통계 재생성 과정에서 수억 건 데이터를 한 번에 읽어 OOM 발생
- 월·일 단위로 나눠야 하는 대량 처리 요구와 안정성·정합성 확보 필요
구조와 흐름
- Manager Step이 Partitioner로 날짜 범위 분할, PartitionHandler가 Worker Step 병렬 실행
- 각 Worker Step은 독립적인 ExecutionContext로 자기 구간만 처리
- 분할→실행→취합 흐름으로 전체 배치 상태를 마무리
해결 방법
- Partitioning으로 월/일 단위 단계 분할 후 병렬 처리
- MongoCursorItemReader로 커서 스트리밍 읽기 적용해 메모리 점유 최소화
- Bulk Operations UNORDERED로 일괄 쓰기 처리해 네트워크 왕복과 GC 부담 감소
성능/운영 포인트
- gridSize와 ThreadPoolTaskExecutor 설정이 성능 좌우
- cursorBatchSize, queueCapacity, corePoolSize 같은 값 튜닝 필요
- 단순 병렬화만으로는 부족하고 읽기·쓰기 최적화 결합이 중요
주의할 점
- Partitioning은 설정 복잡도와 학습 곡선이 높음
- MongoPagingItemReader의 skip 오버헤드는 대용량 처리에 비효율적
- Aggregation Pipeline은 이번처럼 단순 순차 조회 목적에는 부적합
