#Backend

Spring Data Redis: Repository vs RedisTemplate — 실전 성능 비교

Spring Data Redis: Repository vs RedisTemplate — 실전 성능 비교
01

Summary

레디스 CPU 100%의 주범은 @RedisHash? 성능을 3배 높인 여기어때의 최적화 비결

편리함 뒤에 숨겨진 Spring Data Redis Repository의 성능 함정을 파헤치고 RedisTemplate으로 장애를 해결한 실전 기록

이 아티클은 대규모 트래픽을 처리하는 서비스에서 Spring Data Redis의 Repository 추상화가 어떻게 시스템 장애를 유발할 수 있는지 심층적으로 분석합니다. 실제 프로덕션 환경의 복잡한 객체 구조를 바탕으로 Repository와 RedisTemplate의 내부 동작 원리를 비교하며, 단순한 API 교체만으로 CPU 부하를 90% 줄인 실무적인 해결책을 제시합니다. 벤치마크 데이터와 Redis 모니터링 로그를 통해 성능 최적화의 근거를 명확히 보여주는 것이 특징입니다.

  • 01피크 타임 Redis CPU 포화 상태를 해결하기 위해 진행한 트러블슈팅 및 근본 원인 분석 과정 공개
  • 02Spring Data Redis Repository가 내부적으로 다중 명령어(HMSET, SADD)를 실행하며 발생하는 성능 오버헤드 지적
  • 031,600개 이상의 필드를 가진 복잡한 도메인 객체가 Redis 엔진에 주는 실제 부하 수치 확인
  • 04JMH 벤치마크를 통해 검증된 RedisTemplate의 압도적인 저장(2.45배) 및 조회 성능 지표
  • 05메모리 사용량을 1.6배 절감하며 수 GB의 인프라 비용을 아낄 수 있는 데이터 구조 최적화 팁

RECOMMENDATION

단순 Key-Value 캐싱이 목적이거나 고성능이 필요한 대용량 트래픽 환경이라면 Spring Data Redis의 Repository 대신 RedisTemplate 사용을 강력히 권장합니다.

The Problem

여기어때 전시 개발 팀에서 피크 타임에 Redis CPU 사용률이 100%에 도달하며 전체 서비스 응답 시간이 3~5배 증가하고 타임아웃 장애가 발생했습니다. 원인 분석 결과, Spring Data Redis의 CrudRepository(@RedisHash)가 객체 저장 시 복잡한 Hash 구조와 보조 인덱스 관리를 위해 다수의 Redis 명령어를 실행하여 엔진에 부하를 준 것으로 확인되었습니다.

The Solution

기존의 Repository 방식 대신 RedisTemplate의 opsForValue().set()을 활용하여 객체를 단순 JSON String 형태로 저장하도록 변경했습니다. 이를 통해 객체 하나를 저장할 때마다 실행되던 다수의 HMSET, SADD 명령어를 단일 SET 명령어로 최적화하고 불필요한 보조 인덱스 생성을 제거했습니다.

The Result

Redis CPU 사용률이 100%에서 10% 수준으로 90% 감소했고, 서비스 응답 시간이 150ms에서 50ms로 3배 개선되었습니다. JMH 벤치마크 결과 저장 성능은 2.45배, 조회 성능은 1.35배 향상되었으며, 보조 자료구조 제거를 통해 메모리 사용량 또한 약 1.6배 절감하는 성과를 거두었습니다.

Trade-off

Repository 방식이 제공하는 JPA 스타일의 편리한 CRUD 기능과 자동 인덱스 관리 기능을 사용할 수 없게 되어 개발자가 직접 JSON 직렬화 및 키 관리 로직을 구현해야 합니다. 또한 Redis 내에서 필드 단위의 부분 수정이나 복잡한 쿼리가 어려워지므로 데이터 접근 패턴에 따른 신중한 선택이 필요합니다.

03

Key Concepts

Concept · 01

Spring Data Redis Repository

JPA와 유사한 인터페이스 방식으로 Redis 데이터를 다룰 수 있게 해주는 고수준 추상화 레이어입니다.

  • 도메인 객체를 Redis Hash 구조로 변환하며 모든 키 목록을 관리하기 위한 별도의 Set을 생성합니다.
  • 객체 하나를 저장할 때마다 내부적으로 다중 Redis 명령어를 실행하여 네트워크 및 엔진 부하를 유발할 수 있습니다.
Concept · 02

RedisTemplate

Redis의 데이터 타입에 직접 접근하여 세밀하게 연산을 제어할 수 있는 Spring의 핵심 API 클래스입니다.

  • opsForValue()를 통해 객체를 JSON 등으로 직접 직렬화하여 단일 SET 명령어로 저장할 수 있습니다.
  • 불필요한 인덱스 관리나 부가 명령어 실행이 없어 Repository 방식보다 속도가 빠르고 리소스 사용이 효율적입니다.
Concept · 03

Secondary Indexing in Redis

기본 키 외의 필드로 검색하기 위해 Redis가 내부적으로 추가 자료구조(Set, Sorted Set)를 생성해 관리하는 방식입니다.

  • Repository의 @Indexed 어노테이션을 통해 구현되며, 데이터 저장 및 삭제 시 인덱스 동기화를 위한 추가 연산이 발생합니다.
  • 데이터 규모가 커질수록 인덱스 관리 비용이 기하급수적으로 증가하여 CPU 및 메모리 부하의 원인이 됩니다.