Skip to content

[refactor] 전체 도서 조회 로직 개선#88

Merged
eun-seoo merged 9 commits intodevelopfrom
refactor/distinct
Feb 11, 2026
Merged

[refactor] 전체 도서 조회 로직 개선#88
eun-seoo merged 9 commits intodevelopfrom
refactor/distinct

Conversation

@eun-seoo
Copy link
Member

@eun-seoo eun-seoo commented Feb 11, 2026

📌 작업한 내용

기존 로직은 전체 도서 테이블을 메모리에 로딩한 뒤 애플리케이션 레벨에서 가공하고 있었습니다.
이로 인해 실제로는 고유한 categoryId, genreId 몇 개만 필요함에도 불구하고
도서가 10,000권이면 10,000개의 Book 객체가 모두 메모리에 로딩되는 구조였습니다.

이를 개선하기 위해 DB 레벨에서 DISTINCT 쿼리를 수행하도록 리팩토링했습니다.

  • 도서 수와 무관하게 실제 필요한 ID 개수만 반환
  • 메모리 사용량 감소
  • 불필요한 객체 생성 제거

캐시 구성

캐시명 용도 TTL
distinctCategoryIds 고유 카테고리 ID 목록 24시간
distinctGenreIds 고유 장르 ID 목록 24시간
categoryBooks 특정 카테고리의 도서 목록 6시간
genreIdBooks 특정 장르의 도서 목록 6시간
userStatistics 사용자 통계 30분

🔍 참고 사항

JMeter 테스트 중 Redis 캐시 직렬화 이슈 해결

JMeter 부하 테스트 과정에서 Redis 캐시 역직렬화 오류가 발생했습니다.
원인은 직렬화 설정 변경 과정에서 기존 캐시 데이터와 새로운 직렬화 형식이 호환되지 않았고,
타입 정보 누락, Boolean 필드명 규칙, Java Time 타입 미지원 등이 복합적으로 작용한 것으로 보입니다,,🥺

이를 해결하기 위해 다음과 같이 조치했습니다.

  • activateDefaultTyping 적용으로 @class 기반 타입 정보 저장
  • jacksonObjectMapper() 사용으로 Kotlin 클래스 안정적 지원
  • JavaTimeModule 등록으로 LocalDate, LocalDateTime 직렬화 지원
  • @JsonProperty 적용으로 Boolean 필드명 불일치 문제 해결
  • 직렬화 설정 변경 후 Redis 캐시 초기화(FLUSHALL) 수행

해당 수정 이후 JMeter 테스트 환경에서 Redis 캐시를 정상적으로 저장·조회함을 확인했습니다!

JMeter Thread Group 설정

동시 사용자 수 100명이 10초에 걸쳐 진입하고, 1분간 무한 반복하는 테스트를 유지하도록 설정했습니다.

🖼️ 스크린샷

캐싱 전

image

캐싱 후

image

캐싱 적용 전에는 최대 응답 시간이 약 72ms까지 상승하며, 부하 증가 시 DB 영향으로 인해 응답 시간이 급격히 증가하는 구간이 확인되었습니다. 반면 캐싱 적용 후에는 최대 응답 시간이 약 59ms로 감소하고 변동 폭도 줄어들어, 부하 상황에서도 보다 안정적으로 수렴하는 패턴을 보였습니다.

다만 그래프의 차이가 생각보다 크지 않은 것을 확인할 수 있는데,, 기존 시스템의 기본 성능이 이미 양호했기 때문에 평균 응답 시간의 큰 차이는 나타나지 않았다고 보이며, 캐싱은 평균 속도 개선보다는 최대 지연 시간 감소와 안정성 향상 측면에서 의미 있는 효과를 보였습니다.
향후 트래픽이 증가할 경우 고부하 환경에서 그 효과가 더욱 뚜렷해질 것으로 예측됩니다!!

리뷰어분들께,,,💖

더 정확한 테스트를 할 수 있는 테스트 환경을 추천해주시면 감사하겠습니다!ㅜ.ㅜ 🫠

🔗 관련 이슈

#60

✅ 체크리스트

  • 로컬에서 빌드 및 테스트 완료
  • 코드 리뷰 반영 완료
  • 문서화 필요 여부 확인

@eun-seoo eun-seoo self-assigned this Feb 11, 2026
@eun-seoo eun-seoo added the 🔨 Refactor 코드 리팩토링 label Feb 11, 2026
@eun-seoo eun-seoo linked an issue Feb 11, 2026 that may be closed by this pull request
1 task
@eun-seoo eun-seoo added 🐞BugFix Something isn't working ✨ Feature 기능 개발 labels Feb 11, 2026
Copy link
Collaborator

@sispo3314 sispo3314 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DB레벨에서 필요한 ID만 가져오는 방식으로 변경하셨네요!! 확실히 메모리 효율과 비용 측면에서 모두 좋은 개선 방향 같습니다! JMeter를 통한 성능 측정까지 잘 해주신 것 같아요 👍👍

Copy link
Member

@AtMach10 AtMach10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 성능 개선 → 부하 테스트 → 문제 발견 → 재설계 → 검증까지 이어진 흐름이 잘 보여서 좋은 개선이라고 느꼈습니다👏

@Query("SELECT b FROM Book b WHERE b.genreId = :genreId")
fun findAllByGenreId(@Param("genreId") genreId: Long): List<Book>

@Query("SELECT DISTINCT b.categoryId FROM Book b")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DISTINCT 쿼리로 불필요한 객체 생성을 제거하고, 메모리 사용까지 감소해서 좋은 리팩토링 같아요~👍

@eun-seoo eun-seoo merged commit c4388f5 into develop Feb 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞BugFix Something isn't working ✨ Feature 기능 개발 🔨 Refactor 코드 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[refactor] 선호 정보 미존재 시 전체 도서 조회 로직 개선

3 participants