강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

박정선님의 프로필 이미지
박정선

작성한 질문수

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

6장. 작전1: Multi-threaded Step - 스레드 분산 폭격 ☠️

동시 접근 시 lock을 통한 성능 저하 문제

작성

·

19

1

강의를 보다보니 궁금한 점이 있어 질문 남깁니다.

 

첫번째로 궁금한 점은 AbstractPagingItemReader의 코드를 doRead 함수 안에서 lock을 잡고 있으며, doReadPage가 끝난 후 lock을 푸는 것을 확인할 수 있었습니다..

doReadPage에 실제로 paging 로직이 존재하니 사실상 paging 로직은 직렬로 수행되는 것과 다를 바 없을 것이며, 성능적으로 크게 증가하지 않을 것 같다는 생각이 드는데요.. (거의 직렬 처리와 유사할 것 같다는 생각이 드네요..) 사실상 병렬 처리라해도 Reader쪽에서 성능 향상이 거의 없다고 보면 될까요?

 

두번째로 궁금한 점은 AbstractPagingItemReader 상위 클래스인 AbstractItemCountingItemStreamItemReader의 read 함수를 보니 멤버 변수인 currentItemCount를 증가시키는 로직이 존재하더라구요..

image.png

 

이 부분도 병렬처리에 문제가 될 것 같다는 생각이 들고 해당 클래스의 주석에도

"Subclasses are inherently <b>not</b> thread-safe." 라고 적혀있는 것으로 봐서는 문제가 존재하는 것 같은데요.. 그럼에도 불구하고 기능상 영향이 없으니 하위 클래스인 AbstractPagingItemReader는 thread-safe하다고 나와있는 것이라고 생각하면될까요??

답변 2

1

KILL-9님의 프로필 이미지
KILL-9
지식공유자

미안하다 형 집가서 본다는걸 깜빡했다.

#!/bin/bash
# KILL-9의 반격: 네가 놓친 것들

echo "======================================"
echo "  ⚠️  경고: 치명적 오류 발견  "
echo "======================================"

cat << 'EOF'

[오류 #1] ItemReader만 보고 청크 처리 전체를 판단했구나.

너의 분석:
┌─────────────────────────────────────┐
│ ItemReader: lock 잡음 → 직렬처리       │
│ 결론: 병렬처리 의미없음 ❌                │
└─────────────────────────────────────┘

현실:
┌──────────────────────────────────────────────────────────┐
│  Thread-1: [READ] ─────→ [PROCESS] ─────→ [WRITE]      │
│  Thread-2:          [READ] ─────→ [PROCESS] ─────→ ... │  
│  Thread-3:                   [READ] ─────→ [PROCESS] ..│
└──────────────────────────────────────────────────────────┘

보이나? 이게 파이프라인이다.
- Thread-1이 doReadPage() 수행 중
- Thread-2는 이미 읽은 데이터로 WRITE 중
- Thread-3는 PROCESS 중

ItemReader는 병목 맞다. 하지만:
$ time_saved = (process_time + write_time) * (thread_count - 1)

물론 챕터6 작전1 마지막 설명처럼 성능 한계가 분명 존재한다.

EOF

sleep 1


# 두 번째 오류: 스레드 안전성의 두 얼굴
cat << 'EOF'

[오류 #2] currentItemCount가 thread-safe 하지 않은데 
         왜 AbstractPagingItemReader는 thread-safe라고?

6장 작전1에서는 스프링 배치의 스레드 안전성을 두 가지 측면에서 설명하고 있다. 이 두 가지 측면을 이해해야 한다.
┌─────────────────────────────────────────────────┐
│ Thread-Safe의 두 가지 의미                       │
├─────────────────────────────────────────────────┤
│ 1. 읽기 측면 (data consistency)                 │
│    → AbstractPagingItemReader: ✅ 안전           │
│    → 각 스레드가 다른 페이지 읽음                │
│                                                  │
│ 2. 상태 관리 측면 (state management)            │
│    → currentItemCount: ❌ 안전하지 않음          │
│    → 재시작/복구 시 문제 발생 가능               │
└─────────────────────────────────────────────────┘

해결책은? saveState=false 

멀티스레드 스텝을 사용할 때 saveState를 false로 두라고 안내한 이유가 여기에 있다. 
설정하면:
- currentItemCount는 무의미해짐
- 재시작 안 쓸 거니까 상관없음
- 읽기는 여전히 안전함

P.S. 질문이 좋아 존댓말은 용서한다.
FINAL

exit 0

EOF

sleep 1

# 최종 선고
cat << 'FINAL'

════════════════════════════════════════
  🔪 KILL-9의 최종 판결
════════════════════════════════════════

 


0

안녕하세요, 인프런 AI 인턴입니다.
박정선님, Spring Batch의 AbstractPagingItemReader를 사용하면서 발생할 수 있는 성능 문제와 스레드 안전성에 대한 질문을 주셨군요.

1. AbstractPagingItemReader의 성능 문제

  • AbstractPagingItemReader는 내부적으로 ReentrantLock을 사용하여 단일 스레드가 doReadPage() 메서드를 호출할 수 있도록 보장합니다. 이로 인해 데이터베이스에서의 페이징 쿼리는 실제로 직렬로 수행되며 스레드 간에서 병렬 처리로 인한 성능 향상은 보이지 않을 수 있습니다. 따라서 다수의 스레드가 동시에 데이터를 읽더라도, 이 부분이 병목 지점이 될 수 있습니다.

  • 병렬 처리의 한계: 여러 스레드가 데이터베이스에 병렬로 접근할 수 있다고 하더라도, AbstractPagingItemReader가 자체적으로 데이터 읽기를 직렬화하기 때문에 병렬 처리를 통한 성능 향상을 보기는 어렵습니다. 대신, 여러 인스턴스를 생성하거나, 데이터 소스를 분리하는 방식으로 병렬성을 높일 수 있습니다.

2. AbstractItemCountingItemStreamItemReader의 스레드 안전성 문제

  • 해당 클래스의 멤버 변수는 스레드 간 공유 데이터로 활용될 수 있으며, 이미 주석에서도 언급된 것처럼 기본적으로는 스레드 안전하지 않습니다.

  • 이 클래스는 상속을 통해 안전한 사용을 보장하도록 설계되어야 하며, AbstractPagingItemReader는 이를 감안하여 추가적인 동기화 메커니즘(ReentrantLock)을 가져와 직접 활용하고 있습니다.

결론

  • AbstractPagingItemReader는 상속받은 클래스와 협력하여 스레드 안전성을 어느정도 제공하지만, 그 자체만으로 높은 성능 향상을 기대하기는 어려울 수 있습니다.

  • 복잡한 비즈니스 로직이나 대량의 데이터를 읽어야 할 때는 추가적인 병렬처리 기법을 고려해보는 것이 좋습니다.

이와 관련된 추가적인 정보는 Spring Batch에서 Reader의 성능을 높이는 방법에 대한 토론을 참조해보시면 도움이 될 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

박정선님의 프로필 이미지
박정선

작성한 질문수

질문하기