개발놀이터

스프링 배치 CursorItemReader vs PagingItemReader 본문

Spring/Spring Batch

스프링 배치 CursorItemReader vs PagingItemReader

마늘냄새폴폴 2022. 9. 5. 18:16

스프링 배치에서는 각기 다양한 ItemReader를 제공하는데 그 중 CursorItemReader 와 PagingItemReader는 언뜻 보기에 비슷해 보이고 실제로도 하는 일이 비슷합니다.

 

그래서 이번 포스팅에선 이 둘의 차이점에 대해 탐구해보는 시간을 가져보도록 하겠습니다. 

 

 

ItemReader

우선 ItemReader에 대해서 짚고 넘어가야 할 것 같습니다. 

 

ItemReader란 뭘까요?

 

스프링 배치의 구성도

스프링 배치의 ItemReader는 데이터를 읽어들이는 일을 합니다. 그게 꼭 DB의 데이터만을 얘기하진 않습니다. File, XML, JSON 등 다른 데이터 소스를 배치 처리의 입력으로 사용할 수 있습니다. 

 

이외에도 Spring Batch에서 지원하지 않는 Reader가 필요한 경우 직접 해당 Reader를 만들 수 있습니다. Spring Batch는 이를 위해 Custom Reader 구현체를 만들기 쉽게 제공하고 있습니다. 

 

 

대표적인 구현체로 JdbcPagingItemReader가 있는데요. 해당 ItemReader의 관계도에 대해 먼저 알아보겠습니다. 관계도를 보시면 오늘의 문제에 대한 답이 어느정도 나옵니다!

 

출처 : https://jojoldu.tistory.com/336

 

보시면 최 상위 인터페이스에 ItemReader, ItemStream이 있는 것을 확인할 수 있는데요.

 

각각을 살펴보도록 하겠습니다.

 

ItemReader를 살펴보면 read()만 가지고 있습니다. read()의 경우 데이터를 읽어오는 메서드입니다.

 

그럼 ItemStream은 무슨 역할을 할까요?

 

ItemStream 인터페이스는 주기적으로 상태를 저장하고 오류가 발생하면 해당 상태에서 복원하기 위한 마커 인터페이스입니다. 이렇게 말하면 역시 이해하기 힘들겠죠

 

즉 ItemStream은 ItemReader의 상태를 저장하고 실패한 곳에서 다시 시작할 수 있게 해주는 역할을 합니다. 쉽게 생각해서 데이터베이스와 애플리케이션 사이에 통로를 하나 연결하고 하나씩 빨아들인다고 생각하면 됩니다.

 

JSP나 Servlet으로 게시판을 작성할 때 ResultSet을 사용해서 next()로 하나씩 데이터를 가져왔던 것을 생각하시면 됩니다.

 

ItemReader에 대해서 더 자세히 알고 싶으신 분들은 향로(jojoldu)님 블로그에 가시면 자세한 내용을 만나보실 수 있습니다.

 

https://jojoldu.tistory.com/336

 

7. Spring Batch 가이드 - ItemReader

앞의 과정들을 통해 Spring Batch가 Chunk 지향 처리를 하고 있으며 이를 Job과 Step으로 구성되어 있음을 배웠습니다. Step은 Tasklet 단위로 처리되고, Tasklet 중에서 ChunkOrientedTasklet을 통해 Chunk를 처..

jojoldu.tistory.com

 

그럼 이제 본론으로 들어가볼까요?

 

제가 이 ItemStream과 ItemReader에 대해서 왜 얘기를 꺼냈을까요? 어느정도 눈치가 빠르신 분들은 눈치채셨을겁니다. 바로 CursorItemReader와 PagingItemReader가 각각 ItemStreamReader, ItemReader이기 때문인데요. 

 

공식문서에서는 이를 어떻게 표현하고 있을지 궁금해서 공식문서를 찾아봤습니다. 

 

https://docs.spring.io/spring-batch/docs/current/reference/html/readersAndWriters.html#databaseReaders

 

ItemReaders and ItemWriters

So far, only delimited files have been discussed in much detail. However, they represent only half of the file reading picture. Many organizations that use flat files use fixed length formats. An example fixed length file follows: The following example sho

docs.spring.io

 

HibernateCursorItemReader

해석하면 이정도로 해석할 수 있습니다.

 

"HibernateCursorItemReader는 하이버네이트의 상단에 위치한 데이터베이스 기록을 읽는 ItemStreamReader이다. 이것은 HQL쿼리로 실행되고 시작될 때 read()메서드가 호출되면서 결과들이 반복자를 통해 현재 행에 해당하는 개체를 순차적으로 반환한다. 스프링 배치는 HibernateCursorItemReader인스턴스를 생성하기 위한 HibernateCursorItemReaderBuilder를 제공한다"

 

HibernatePagingItemReader

이것도 해석하면 이런 내용입니다.

 

"HibernatePagingItemReader는 하이버네이트의 상단에 위치한 데이터베이스 기록을 읽는 ItemReader이다. 그리고 한번에 아이템의 숫자를 고정해서 읽어온다. 스프링 배치는 HibernatePagingItemReader인스턴스를 생성하기 위한 HibernatePagingItemReaderBuilder를 제공한다."

 

둘의 내용을 봤을 때 CursorItemReader와 PagingItemReader에 대해서 다른 내용은 CursorItemReader는 반복자를 통해 현재 행에 해당하는 개체를 "순차적으로" 반환한다. PagingItemReader는 "한번에" 아이템의 숫자를 고정해서 읽어온다.

 

이제 둘의 차이에 대해 아시겠죠?

 

 

둘의 차이점에 대해 더 자세한 궁금증을 가진 외국인 질문자가 스택오버플로우에 남긴 질문을 보시죠. 

 

https://stackoverflow.com/questions/20386642/spring-batch-which-itemreader-implementation-to-use-for-high-volume-low-laten

 

Spring Batch: Which ItemReader implementation to use for high volume & low latency

Use case: Read 10 million rows [10 columns] from database and write to a file (csv format). Which ItemReader implementation among JdbcCursorItemReader & JdbcPagingItemReader would be suggested...

stackoverflow.com

 

질문자의 질문은 이렇습니다.

 

"ItemReader의 구현체 중에서 JdbcCursorItemReader와 JdbcPagingItemReader중에 어떤 것을 추천하나요? 그리고 그 이유는 뭔가요?"

 

뒤이은 질문은 이렇습니다. 

 

"둘 중 사용했을 때 성능상 더 빠른건 뭔가요?"

 

첫번째 질문에 대한 답변은 이렇습니다.

 

It really depends on the database you're using, driver options available as well as processing models you can support. Another consideration is, do you need restartability?

 

해석하면 대충 이런 내용입니다. "그 둘의 선택은 네가 무슨 데이터베이스를 쓰는지 어떤 드라이버 옵션을 가지고 있는지에 따라 다르다."

 

두번째 질문에 대한 답은 이렇습니다.

 

"Again it depends on your processing model chosen."

 

"이 질문 역시 네가 선택한 수행 모델에 따라 다르다"

 

 

왜 수행 모델에 따라 다르다고 했을까요? 이제 본격적으로 둘의 차이점에 대해 알아보도록 하겠습니다. 

 

 

ItemCursorReader

ItemCursorReader는 기본적으로 JDBC ResultSet 의 기본 매커니즘을 사용합니다. 

 

현재 행에 커서를 유지하며 다음 데이터를 호출하면 다음 행으로 커서를 이동하며 데이터 반환이 이루어지는 Streaming 방식의 I/O 입니다. 

 

ResultSet이 open 될 때마다 next() 메서드가 호출 되어 DB의 데이터가 반환되고 객체와 매핑이 이루어집니다. 

 

DB Connection이 연결되면 배치 처리가 완료될 때까지 데이터를 읽어오기 때문에 DB와 SocketTimeout을 충분히 큰 값으로 설정할 필요가 있습니다. 

 

모든 결과를 메모리에 할당하기 대문에 메모리 사용햘잉 많아지는 단점이 있습니다. 하지만 Connection 연결 유지 시간과 메모리 공간이 충분하다면 대량의 데이터 처리에 적합할 수 있습니다. 

 

 

ItemPagingReader

ItemPagingReader는 페이징 단위로 데이터를 조회하는 방식으로 Page Size만큼 한번에 메모리로 가지고 온 다음 한 개씩 읽습니다. 

 

한 페이지를 읽을 때마다 Connection을 맺고 끊기 때문에 대량의 데이터를 처리하더라도 SocketTimeout 예외가 거의 일어나지 않습니다. 

 

시작 행 번호를 지정하고 페이지에 반환시키고자 하는 행의 수를 지정한 후 사용합니다. (Offset, Limit 사용)

 

페이징 단위의 결과만 메모리에 할당하기 때문에 메모리 사용량이 적어지는 장점이 있습니다. 따라서 Connection 연결 유지 시간이 길지 않고 메모리 공간을 효율적으로 사용해야 하는 데이터 처리에 적합할 수 있습니다. 

 

 

이렇게 ItemCursorReader와 ItemPagingReader에 대해서 알아봤습니다. 둘의 차이에 대해서 확실히 이해 하셨나요? 긴 글 읽어주셔서 감사합니다. 다음 포스팅에서 뵐게요~

 

 

 

Reference

https://jojoldu.tistory.com/336

 

7. Spring Batch 가이드 - ItemReader

앞의 과정들을 통해 Spring Batch가 Chunk 지향 처리를 하고 있으며 이를 Job과 Step으로 구성되어 있음을 배웠습니다. Step은 Tasklet 단위로 처리되고, Tasklet 중에서 ChunkOrientedTasklet을 통해 Chunk를 처..

jojoldu.tistory.com

https://docs.spring.io/spring-batch/docs/current/reference/html/readersAndWriters.html#databaseReaders

 

ItemReaders and ItemWriters

So far, only delimited files have been discussed in much detail. However, they represent only half of the file reading picture. Many organizations that use flat files use fixed length formats. An example fixed length file follows: The following example sho

docs.spring.io

https://stackoverflow.com/questions/20386642/spring-batch-which-itemreader-implementation-to-use-for-high-volume-low-laten

 

Spring Batch: Which ItemReader implementation to use for high volume & low latency

Use case: Read 10 million rows [10 columns] from database and write to a file (csv format). Which ItemReader implementation among JdbcCursorItemReader & JdbcPagingItemReader would be suggested...

stackoverflow.com