# Redis에서의 기본 직렬화 설정
Spring에서 RedisTemplate을 사용할 때, 직렬화 설정을 명시적으로 하지 않으면, 기본적으로 Redis는 JdkSerializationRedisSerializer를 사용합니다. 이 직렬화기는 Java의 직렬화 메커니즘을 활용하여 객체를 바이트 스트림으로 변환합니다.
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 기본적으로 직렬화 설정이 없는 경우 JdkSerializationRedisSerializer가 사용됩니다.
return template;
}
}
위 코드에서 StringRedisSerializer를 명시적으로 설정하지 않으면, 키와 값 모두 JdkSerializationRedisSerializer
를 사용하게 됩니다.
# JdkSerializationRedisSerializer의 문제점
JdkSerializationRedisSerializer는 Java 객체를 직렬화하고 이를 바이트 배열로 변환하여 저장합니다. 하지만 이 방식에는 몇 가지 중요한 단점이 있습니다:
- 호환성 문제: Java 직렬화된 객체는 다른 언어 또는 다른 시스템과의 호환성이 부족합니다. 이는 Redis가 여러 시스템 간의 데이터 교환을 처리할 때 문제가 될 수 있습니다.
- 데이터 가독성: 직렬화된 데이터가 바이트 배열로 저장되기 때문에, Redis 클라이언트를 통해 데이터를 직접 확인하기 어렵습니다. 문자열처럼 읽을 수 있는 데이터가 아닙니다.
- Redis 키 문제: 기본적으로 키도 JdkSerializationRedisSerializer에 의해 직렬화되므로, 키가 복잡한 바이트 배열로 저장될 수 있습니다. 이는 데이터 검색 시 예기치 않은 동작을 초래할 수 있습니다.
# @Cacheable과 StringRedisSerializer 사용의 중요성
@Cacheable 어노테이션은 메소드의 결과를 캐시에 저장하고, 이후 동일한 메소드 호출이 있을 경우 캐시에서 데이터를 반환하도록 합니다. 예를 들어, 다음과 같이 @Cacheable을 사용한다고 가정해봅시다:
@Cacheable(value = "userCache", key = "#userId")
public User getUserById(String userId) {
// 데이터베이스 또는 다른 서비스 호출
}
만약 StringRedisSerializer를 사용하지 않고 기본 설정을 유지한다면, Redis에 저장되는 키와 값은 모두 JdkSerializationRedisSerializer를 통해 직렬화됩니다. 이 경우, 키(userId)는 복잡한 바이트 배열로 직렬화되어 저장됩니다.
문제는, Redis에서 키를 검색할 때 @Cacheable 어노테이션이 단순한 문자열을 키로 사용하려고 시도하지만, Redis에 저장된 키는 직렬화된 바이트 배열이므로 일치하지 않게 됩니다. 결과적으로, 캐시에서 데이터를 찾지 못하고 항상 "데이터가 없는" 상태로 메소드가 실행됩니다.
# 해결 방법: StringRedisSerializer 사용
이 문제를 해결하기 위해 StringRedisSerializer를 사용하여 키를 직렬화하는 것이 좋습니다. 아래 코드를 통해 Redis에 저장되는 키를 문자열로 직렬화할 수 있습니다
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 키를 문자열로 직렬화
template.setKeySerializer(new StringRedisSerializer());
// 값을 Java 직렬화로 유지할 수도 있습니다.
template.setValueSerializer(new JdkSerializationRedisSerializer());
return template;
}
}
이렇게 설정하면, @Cacheable에서 사용하는 키(userId)가 Redis에 문자열로 저장되고, 이후 검색할 때도 동일한 형식으로 비교가 이루어져 정상적으로 캐시된 데이터를 찾을 수 있습니다.
# 결론
Redis에서 Spring을 사용할 때 직렬화 설정은 매우 중요합니다. 기본적으로 사용되는 JdkSerializationRedisSerializer는 호환성 문제와 가독성 문제를 일으킬 수 있으며, @Cacheable과 같은 기능이 의도한 대로 동작하지 않을 수 있습니다. 이를 방지하기 위해 StringRedisSerializer를 사용하여 키를 명확하게 문자열로 직렬화하는 것이 좋습니다. 이를 통해 Redis에 저장되는 데이터가 예상대로 동작하고, 캐시에서 데이터를 정확하게 조회할 수 있습니다.
'Java' 카테고리의 다른 글
[JWT] Spring Boot에서 JWT(Json Web Token) 적용하기 (0) | 2024.09.04 |
---|---|
[Spring] 왜 자주 사용하는 객체들을 자동으로 빈으로 등록하지 않을까? (0) | 2024.08.30 |
[Spring] 생성자 주입이 필요한 이유 (0) | 2024.08.23 |
[Bean, Proxy] 왜 @Cacheable이 동작하지 않을까? (0) | 2024.08.21 |
[Redis] Redis란? (0) | 2024.08.16 |