HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
✍🏻
Learnary (learn - diary)
/Batch/
SpringBatch 멀티쓰레드 환경에서의 Reader, Writer 선별 주의사항

SpringBatch 멀티쓰레드 환경에서의 Reader, Writer 선별 주의사항

 
멀티스레드 환경에서 Item 컴포넌트를 확인해야 하는 이유문서 기반 이해안전함을 보장하기 위한 PageReaderItem 의 동기화방식

멀티스레드 환경에서 Item 컴포넌트를 확인해야 하는 이유


배치 성능을 높이기 위해 멀티쓰레드를 사용하면서 유의사항을 발견하였습니다.
 
기존 사용하던 아이템 컴포넌트들은 안전하지 않을 수 있다라는 문구를 보았으며, 그래서 제가 사용하는 아이템 컴포넌트는 이상이 없는지 확인하게되었습니다. 약간 의심이 들어 마저 읽어보면서 일부 모델들을 제공한다고 한다. 그래서 지금은 멀티스레드 기반으로 성능을 높이기 위해 해당 구조를 점검하게 되었습니다.
 
그 결과 일부 제공하는 JdbcPageItem 과 JpaPageItem 은 쓰레드 세이프 하였으며 CursorPageItem은 쓰레드 세이프 하지 않다는 사실을 알게되었습니다.
 
 

문서 기반 이해


 
Scaling and Parallel Processing :: Spring Batch
Scaling and Parallel Processing :: Spring Batch

Scaling and Parallel Processing :: Spring Batch

Many batch processing problems can be solved with single-threaded, single-process jobs, so it is always a good idea to properly check if that meets your needs before thinking about more complex implementations. Measure the performance of a realistic job and see if the simplest implementation meets your needs first. You can read and write a file of several hundred megabytes in well under a minute, even with standard hardware.

In particular, most of the readers and writers from Spring Batch are not designed for multi-threaded use.
 
스프링 배치에서 재공하는 컴포넌트 reader, writer를 멀티스레드 사용을 위해 설계되지 않았다고 합니다.
멀티 쓰레드 스텝을 사용하는 부분에서 주의사항이 있어 이를 좀더 확인하게 되었습니다.
 
Spring Batch provides some implementations of ItemWriter and ItemReader. Usually, they say in the Javadoc if they are thread safe or not or what you have to do to avoid problems in a concurrent environment. If there is no information in the Javadoc, you can check the implementation to see if there is any state. If a reader is not thread safe, you can decorate it with the provided SynchronizedItemStreamReader or use it in your own synchronizing delegator. You can synchronize the call to read(), and, as long as the processing and writing is the most expensive part of the chunk, your step may still complete much more quickly than it would in a single-threaded configuration.
 
몇가지 구현체들을 제공하는데, 꼭 JavaDoc 문서에서thread safe 한지 확인해야 한다라고 권장하고 있습니다.
 
제가 사용하고 자 한 페이징은 JdbcPagingItemReader 이고
이 부분을 문서에서 확인하니, JdbcPagingItemReader (Spring Batch 5.2.2 API)
JdbcPagingItemReader (Spring Batch 5.2.2 API)

JdbcPagingItemReader (Spring Batch 5.2.2 API)

declaration: package: org.springframework.batch.item.database, class: JdbcPagingItemReader

쓰레드 세이프한 문구가 보였습니다.
 
하지만 주의할 점 이 있습니다.
The implementation is thread-safe in between calls to open(ExecutionContext), but remember to use saveState=false if used in a multi-threaded client (no restart available).
‘상태저장’ 을 비활성화하고 restart 도 사용할 수 없다고 합니다.
 
스프링 배치는 각 청크단위의 작업을 모니터링 할 수 있도록 메타테이블에 처리기록을 남기고 이에따라 재시도 및 실패 지점부터 재시작가능한 신뢰성있는 대량처리를 할 수 있는 장점이 있습니다.
 
이 부분을 멀티스레드 환경에서는 서로 다른 일처리로 이에 따라 처리가 제각각으로 이루어질 수 있기에 해당 부분을 사용하면 중복으로 데이터가 처리되기 떄문일것 같습니다.
 
쓰레드 세이프함을 보장하기 위해 어떻게 처리하고 있을지 궁금하여 직접 확인해보았습니다.
결국 JdbcPagingItemReader는 쓰레드 세이프하게 사용할 수 있는 이유는 바로 상위 타입 객체에서 Synchronized 키워드로 이를 동기화하기 때문에 하나의 애플리케이션에서 안정적으로 데이터를 Read가 가능합니다.
 

안전함을 보장하기 위한 PageReaderItem 의 동기화방식


 
AbstractPagingItemReader 상속받은 JdbcPagingItemReader
notion image
 
 
ItemReader와 연관된 객체 컴포넌트들
notion image
 
AbstractPagingItemReader 동기화 코드
notion image