Redis 캐시에 객체를 저장할 때 직렬화가 필요한 이유
Redis 캐시에 객체를 저장할 때 직렬화가 필요한 이유
Spring에서 @Cacheable을 사용해 Redis 캐시를 적용하다 보면, 다음과 같은 예외를 한 번쯤 마주치게 된다.
1
org.springframework.data.redis.serializer.SerializationException: Cannot serialize
처음 이 에러를 접했을 때는 로직이 잘못된 것처럼 보이지만, 실제 원인은 캐시와 객체의 관계를 오해한 데서 시작되는 경우가 대부분이다. 이 글에서는 왜 캐시에 저장되는 객체가 반드시 직렬화 가능해야 하는지, 그리고 Redis 캐시에서 이 문제가 왜 자주 발생하는지 정리해본다.
캐시는 메모리가 아니라 저장소다
로컬 캐시(Caffeine, ConcurrentHashMap 등)를 사용할 때는 객체를 그대로 메모리에 보관한다. 같은 JVM 안에서 동작하기 때문에 객체 참조 자체를 저장해도 문제가 없다.
하지만 Redis는 다르다.
- Redis는 별도의 프로세스다
- 다른 서버에 존재할 수도 있다
- 네트워크를 통해 데이터를 주고받는다
즉, Java 객체를 그대로 둘 수 없고 바이트 단위 데이터로 변환해서 저장해야 한다. 이 변환 과정이 바로 직렬화(Serialization) 다.
Spring Cache + Redis 동작 흐름
@Cacheable이 붙은 메서드가 호출되면 내부적으로 다음 순서로 동작한다.
- 캐시 Key 생성
- Redis에서 Key 조회
- 캐시 미스 시 메서드 실행
- 메서드 반환 값을 직렬화
- Redis에 저장
이 과정에서 4번 단계가 실패하면, 다음과 같은 예외가 발생한다.
1
SerializationException: Cannot serialize
중요한 점은 메서드 실행 자체는 성공한다는 것이다. 즉, 서비스는 정상 응답을 반환하지만 캐시 저장만 실패한다.
결과적으로:
- 캐시는 비어 있고
- 매 요청마다 DB 조회가 발생하며
- 성능 개선 효과는 전혀 얻지 못한다
Redis는 Java 객체를 이해하지 못한다
Redis가 이해할 수 있는 것은 다음과 같은 데이터뿐이다.
- 문자열
- 숫자
- 바이트 배열
- 단순 자료구조(Set, Hash 등)
Java 객체는 Redis 입장에서 보면 의미 없는 데이터다. 그래서 Spring Data Redis는 Serializer를 통해 객체를 변환한다.
대표적인 방식은 두 가지다.
JDK 직렬화
Serializable구현 필요JdkSerializationRedisSerializer사용
JSON 직렬화 (권장)
- Jackson 기반
GenericJackson2JsonRedisSerializer사용
어떤 방식이든 직렬화할 수 없는 객체는 Redis에 저장할 수 없다.
실무에서 자주 발생하는 문제 케이스
Hibernate Entity를 그대로 캐시하는 경우
- Lazy Loading 프록시 포함
- 순환 참조 가능성
- 직렬화 실패 확률 높음
Serializable을 구현하지 않은 DTO
- 기본 Redis 설정(JDK 직렬화)에서 즉시 실패
날짜 타입 처리 미흡
LocalDate,LocalDateTime등 Jackson 설정이 없으면 JSON 직렬화 실패 가능
왜 DTO로 변환해서 캐시해야 할까?
실무에서는 다음 구조가 가장 안전하다.
1
Entity → DTO → Cache
이유는 명확하다.
- DTO는 불변 객체로 설계 가능
- Lazy 프록시 없음
- 직렬화 예측 가능
- 캐시 데이터 구조가 안정적
캐시는 ORM 세션을 연장하는 수단이 아니라, 순수한 데이터 저장소로 다뤄야 한다.
정리
Redis 캐시에 객체를 저장한다는 것은, 객체를 그대로 보관하는 것이 아니라 직렬화된 데이터 형태로 저장한다는 의미다.
따라서:
- 캐시에 들어가는 객체는
- 반드시
- 직렬화 가능해야 한다
이 사실을 놓치면, 캐시는 조용히 실패하고 성능 문제는 눈에 보이지 않게 누적된다.
캐시는 성능 최적화를 위한 도구지만, 직렬화에 대한 이해 없이는 오히려 디버깅이 어려운 문제를 만들 수 있다. Redis 캐시를 사용한다면, 저장되는 객체의 직렬화 가능 여부부터 점검하는 습관이 필요하다.