Java Redis 직렬화 삼총사: Json, String, JDK
덕토피아
이번 포스팅에서는 Java에서 Redis 직렬화 시 자주 사용하는 방법들을 비교하고 각 방식의 특징과 예제를 설명합니다.
JdkSerializationRedisSerializer
JDK 기본 직렬화는 Java 표준 라이브러리에서 제공하는 java.io.Serializable 인터페이스를 사용하여 객체를 바이트 스트림으로 변환하는 방식입니다. 이 방식은 사용하기 편리하지만, 다소 무거운 오버헤드가 있을 수 있습니다.
장점:
Java 내장 기능이라 별도의 라이브러리 필요 없음
복잡한 객체 구조도 쉽게 직렬화 가능
단점:
직렬화된 데이터가 상대적으로 큼
직렬화/역직렬화 과정이 비교적 느림
public class RedisConfig {
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setValueSerializer(new JdkSerializationRedisSerializer());
// 기타 설정
return template;
}
}
저장되는 형태
127.0.0.1:6379> GET user:2
"\xac\xed\x00\x05sr\x00\x04User...\x78\x6f"
StringRedisSerializer
String 직렬화는 데이터를 문자열 형태로 저장하는 방식입니다. 이 방식은 간단하고 가볍기 때문에 기본적인 키-값 저장에 적합합니다. 직렬화 과정 없이 단순히 데이터를 문자열로 변환하여 Redis에 저장합니다.
장점:
속도가 빠르고 갑벼움
데이터가 사람이 읽을 수 있어 디버깅이 쉬움
단점:
객체 직렬화에 비해 유연성이 떨어짐
복잡한 데이터 구조에는 적합하지 않음
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.core.RedisTemplate;
public class RedisConfig {
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
// 기타 설정
return template;
}
}
저장되는 형태
127.0.0.1:6379> GET message
"Hello, World!"
GenericJackson2JsonRedisSerializer
JSON 직렬화는 객체를 JSON 문자열로 변환하는 방식입니다. JSON은 가볍고 사람이 읽을 수 있으며 다양한 언어와 호환이 잘 됩니다. Jackson 라이브러리 등을 활용해 손쉽게 구현할 수 있습니다.
장점:
데이터 포맷이 가볍고 사람이 읽기 쉬움
다양한 언어 간 호환성 우수
객체 타입을 손쉽게 복원 가능
단점:
데이터 크기가 텍스트 기반이라 다소 클 수 있음
이진 데이터보다는 느림
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.core.RedisTemplate;
public class RedisConfig {
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 기타 설정
return template;
}
}
저장되는 형태
127.0.0.1:6379> GET user:1
"{\"@class\":\"com.example.User\",\"name\":\"Alice\",\"age\":25}"
케이스별 선택
여러 언어와의 호환성: GenericJackson2JsonRedisSerializer 추천
같은 언어(Java) 간 데이터 공유: GenericJackson2JsonRedisSerializer 또는 JdkSerializationRedisSerializer 추천
단순 데이터: StringRedisSerializer 추천
복잡한 객체 또는 Java 전용 데이터: JdkSerializationRedisSerializer (단, 모든 서비스가 Java인 경우에만)
저 같은 경우는 서로 다른 서비스에서 동일한 Redis 클러스터를 사용하고 있었습니다. 동일한 프로젝트가 아니었기에 JdkSerializationRedisSerializer은 사용할 수 없었고, 간단한 데이터도 아니었기에 String을 선택하기에도 어려웠습니다.
결국 GenericJackson2JsonRedisSerializer를 선택하였는데, 기본적으로 포함되는 @class 속성은 데이터의 타입 정보를 제공하지만, 다른 서비스에서 필요하지 않았습니다. 이를 비활성화하려면 ObjectMapper 설정을 통해 커스터마이징할 수 있습니다.
다음 내용이 궁금하다면?
이미 회원이신가요?
2024년 11월 10일 오전 10:15
Java 만 쓰고 redis 용으로 직렬화를 한다면 protostuff 도 추천드립니다. 빠르고 별도 정의 없이 사용할 수 있어서요. 직렬화 결과물이 byte 라 사람이 볼 수는 없다는 소소한(?) 단점이 있겠습니다.