[Cache] Redis 직렬화 방법에 대해서

최동근·2023년 5월 15일
0

Cache

목록 보기
2/2

안녕하세요 오늘은 Redis 직렬화 방식에 대해 살펴보겠습니다 💪
우리는 앞서 Spring Data Redis 의존성과 함께 다양한 방법으로 Spring 서버에서 Redis 를 사용해보았습니다. Redis에 대해 알아봅시다(응용편) 를 참고해주세요!

📀 개요

Redis에 대해 알아봅시다.(이론편) & Redis에 대해 알아봅시다.(응용편) 을 먼저 본다면 더욱 빠른 이해를 할 수 있습니다.

앞서 살펴본바와 같이 Spring 에서 Redis 를 사용하기 위해서는 먼저 Spring Data Redis 의존성을 추가해주고, RedisTemplate 혹은 RedisRepository 을 통해 Redis 서버에 접근합니다.
이때 우리가 실행시키고 있는 스프링 서버와 외부에서 실행 중인 레디스 서버는 다른 어플리케이션이기 때문에 데이터에 대한 작업을 위해서는 직렬화/역직렬화 과정이 필요합니다.
이번 포스팅에서는 RedisTemplate Bean 생성시 직렬화 구현체에 대해 알아보겠습니다 ❗️
대표적으로 4가지 JdkSerializationRedisSerializer, GenericJackson2JsonRedisSerializer, Jackson2JsonRedisSerializer,StringRedisSerializer 가 존재합니다.

📀JdkSerializationRedisSerializer

JdkSerializationRedisSerializer 는 Default로 적용되는 Serializer로 기본 자바 직렬화 방식을 사용합니다.

자바에서는 Serializable 인터페이스만 구현하면 별도의 작업 없이 사용가능합니다. 하지만 여러가지 단점이 있습니다.

  • SerialVersionUID 설정을 하지 않으면 클래스의 기본 해시값을 SerialVersionUID 로 사용합니다. 따라서 클래스 구조가 조금이라도 변경시 SerialVersionUID 가 달라서 역직렬화에 실패할 수 있습니다.

  • 만약 개발자가 주의를 가지고 SerialVersionUID 를 설정한다고 하여도, 클래스 내부 필드 타입이 변경되면 역시 역직렬화가 실패할 수 있습니다.

  • 기본적으로 타입에 대한 정보 등 클래스 메타 정보들을 가지고 있기 때문에 직렬화시 용량이 비대해집니다.

따라서, 클래스의 변경이 잦은 경우에는 JdkSerializationRedisSerializer 를 사용하는 것은 지양해야 합니다.

📀 GenericJackson2JsonRedisSerializer

GenericJackon2JsonSerializer 는 Class Type 을 지정할 필요 없이 자동으로 객체를 Json 형식으로 직렬화해주는 장점이 있습니다. 하지만 직렬화된 데이터가 Class Type 을 포함한다는 단점이 있습니다.

또한 직렬화시 @class 필드에는 해당 class 의 패키지까지 함께 저장됩니다.
따라서, 어떤 Application 이던 해당 데이터를 꺼내오기 위해서는 해당 루트, 경로에 같은 이름으로 해당 DTO Class 를 생성해야만 사용이 가능해집니다.

만약 MSA 구조를 가지는 여러 Application 이 상호작용하며 동일한 Domain을 가진다면 MSA API 가 Class Type 에 묶인다는 문제가 발생합니다 🥲

📀Jackson2JsonRedisSerializer

Jackson2JsonRedisSerializer@class 필드를 포함하지 않고 Json 으로 저장해줍니다.
하지만 항상 Class Type 정보를 Serializer 에 함께 지정해주어야합니다.
이는 앞서 살펴보았던 GenericJackson2JsonRedisSerializer와 반대 특징을 가집니다.

이때문에 RedisTemplate 객체를 저장하는 DTO 타입 별로 생성해서 각각의 Serializer의 Class Type 을 지정해주어야 합니다.


@Bean
public RedisTemplate<?,?> redisTemplate() {

	RedisTemplate<?,?> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory());
    redisTemplate.setEnableTranscationSupport(true); // 트랜잭션 지원 가능
    // class Type 지정
    redisTemplate.setKeySerializer(new Jackson2JsonRedisSerializer(String.class));
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(DTO.class));
    
    return redisTemplate;
}

만약 사용하는 Class Type 종류가 많아진다면 큰 단점으로 작용할 수 있습니다 🥲

📀 StringRedisSerializer

결론부터 말하자면 StringRedisSerialier 를 직렬화 구현체로 선택하는 것이 가장 단점을 최소화할 수 있는 방법입니다.

StringRedisSerializer 는 String 값을 그대로 저장하는 Serializer 입니다.
그렇기에 Json 타입으로 별도로 변환하는 과정이 필요하지만 앞서 살펴본 직렬화 구현체들의 단점을 보완할 수 있습니다 ❗️

  • Class Type 별도 지정 필요 x
  • Package 정보를 포함할 필요 x
  • 용량을 최소화하여 저장 o

참고

Spring RedisTemplate Serializer 설정
Spring Boot Redis 두 가지 사용방법 RedisTemplate, RedisRepository
RestTemplate CastClassException 이슈

profile
비즈니스가치를추구하는개발자

0개의 댓글