Spring Batch Chunk 기반 처리 방식이란? (대용량 데이터 필승 전략)

안녕하세요.

“데이터가 1000만 건인데, 이걸 자바 List에 다 담으면 어떻게 될까요?”
아마 OutOfMemoryError와 함께 서버가 뻗어버릴 겁니다.

이런 대재앙을 막기 위해 Spring Batch가 제공하는 가장 강력한 무기가 바로 Chunk(덩어리) 기반 처리입니다. 오늘은 이 Chunk 방식이 도대체 무엇인지, 그리고 어떻게 동작하는지 완벽하게 파헤쳐 보겠습니다.


1. Chunk 기반 처리란? (What)

쉽게 말해 “한 번에 하나씩 읽어서, 뭉텅이로 모았다가, 한 방에 처리하는 방식”입니다.

  • Reader: 데이터를 하나씩 읽어옵니다. (One by One)
  • Processor: 읽어온 데이터를 하나씩 가공합니다. (One by One)
  • Writer: 가공된 데이터가 정해진 개수(Chunk Size)만큼 모이면, 리스트 형태로 받아 한 번에 씁니다. (All at Once)

2. 동작 프로세스 (How)

Chunk Size = 10이라고 가정해 봅시다.

  1. Read & Process 반복:

    • Reader가 1번째 데이터를 읽습니다 -> Processor가 가공합니다 -> 바구니(Buffer)에 담습니다.
    • Reader가 2번째 데이터를 읽습니다 -> Processor가 가공합니다 -> 바구니에 담습니다.
    • … (반복) …
    • Reader가 10번째 데이터를 읽습니다 -> Processor가 가공합니다 -> 바구니에 담습니다.
  2. Write 실행:

    • 바구니에 10개가 꽉 찼습니다!
    • 이 10개를 몽땅 들고 Writer에게 갑니다.
    • Writer는 10개를 DB에 저장(Insert/Update)합니다.
  3. Transaction Commit:

    • 저장이 성공하면 트랜잭션을 커밋합니다. (이때 DB에 반영됨)
    • 바구니를 비우고 다시 1번으로 돌아갑니다.

3. 왜 Chunk 방식을 쓸까? (Why)

3.1 메모리 효율성

1000만 건을 다 메모리에 올리지 않고, 딱 10개(Chunk Size) 만큼만 메모리를 사용합니다. 데이터가 아무리 많아도 메모리 사용량은 일정하게 유지됩니다.

3.2 트랜잭션 성능 및 안정성

  • 성능: DB 입출력(I/O)은 비용이 비쌉니다. 1건마다 커밋하는 것보다, 1000건씩 모아서 한 번에 커밋하는 것이 훨씬 빠릅니다.
  • 안정성: 처리 도중 500번째에서 에러가 나면? 앞선 Chunk(예: 1~400번)들은 이미 커밋되어 안전합니다. 현재 진행 중인 Chunk만 롤백하면 됩니다.

4. 코드 예제

@Bean
public Step chunkStep() {
    return new StepBuilder("chunkStep", jobRepository)
            .<User, User>chunk(100, transactionManager) // Chunk Size = 100
            .reader(userReader())
            .processor(userProcessor())
            .writer(userWriter())
            .build();
}

여기서 .chunk(100, ...)이 바로 “100개씩 끊어서 처리하겠다”는 선언입니다. 이 숫자는 서버의 메모리 용량과 DB 부하를 고려하여 적절히 튜닝해야 합니다. (무조건 크다고 좋은 게 아닙니다!)


5. Chunk Size 튜닝 팁

  • 너무 작으면: 커밋이 너무 자주 일어나 I/O 비용이 증가하여 느려집니다.
  • 너무 크면: 메모리를 많이 잡아 OOM 위험이 있고, 에러 발생 시 롤백되는 범위가 너무 커져서 재처리 부담이 커집니다.
  • 적정값: 보통 100~1000 사이에서 시작하여, 실제 운영 환경에서 테스트하며 최적값을 찾습니다. Paging ItemReader를 쓴다면 Page Size와 Chunk Size를 일치시키는 것이 좋습니다.

6. 결론

Chunk 처리 방식은 대용량 데이터를 다루는 백엔드 개발자의 필수 소양입니다. 이 원리를 이해해야만 수억 건의 데이터도 두려움 없이 처리할 수 있는 진정한 엔지니어로 거듭날 수 있습니다.

관련 글 보기