下面就是关于“SpringDataRedis入门和序列化方式解决内存占用问题小结”的完整攻略。
SpringDataRedis入门
什么是Redis?
Redis(Remote Dictionary Server)是一个开源的基于内存的数据结构存储系统,可以用作数据库、缓存和消息中间件。Redis支持多种类型的数据结构,如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)等。
SpringDataRedis是什么?
SpringDataRedis是Spring Data项目的一部分,它提供了与Redis集成的API。
使用SpringDataRedis
使用SpringDataRedis需要引入相关的依赖包,以下是常用的依赖包:
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
使用SpringDataRedis需要进行配置,以下是一个简单的配置文件示例:
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置key和value的序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30));
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();
}
}
在RedisConfig中,我们使用了@Bean注解来创建RedisTemplate和CacheManager对象。在RedisTemplate创建过程中,我们设置了key和value的序列化方式。通常情况下,我们可以使用默认的StringRedisSerializer来序列化key,使用Jackson2JsonRedisSerializer来序列化value。在CacheManager创建过程中,我们设置了默认的缓存时间为30分钟。
使用SpringDataRedis操作Redis通常使用以下两个类之一:RedisTemplate和StringRedisTemplate。前者可以操作任意类型的数据,后者可以操作字符串类型的数据。
以下是使用RedisTemplate来操作Redis的两个示例:
@Component
public class RedisService {
private final RedisTemplate<String, Object> redisTemplate;
public RedisService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
}
@SpringBootTest
public class RedisServiceTest {
@Autowired
private RedisService redisService;
@Test
public void testSetAndGet() {
String key = "testKey";
String value = "testValue";
redisService.set(key, value);
Object result = redisService.get(key);
Assert.assertEquals(value, result);
}
}
序列化方式解决内存占用问题
在使用Redis时,我们通常会遇到内存占用问题,这时我们可以通过设置合适的序列化方式来解决。
什么是序列化?
序列化(Serialization)是将对象转换为字节流的过程,反序列化(Deserialization)则是将字节流转换为对象的过程。在Java中,使用序列化可以将对象保存到文件中或通过网络传输。
常见的序列化方式
Java默认的序列化方式
Java默认的序列化方式是使用Java原生的ObjectOutputStream和ObjectInputStream进行对象的序列化和反序列化。虽然这种方式使用简单,但是序列化后的对象占用空间大,序列化性能相对较慢。
JSON格式序列化
JSON格式序列化是指将对象序列化为JSON格式的字符串,反序列化则是将JSON格式字符串反序列化为对象。相对于Java默认的序列化方式,JSON格式序列化序列化后的对象占用空间更小,且序列化性能更快。SpringDataRedis默认使用的就是Jackson2JsonRedisSerializer。
以下是使用Jackson2JsonRedisSerializer的示例:
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Object.class)));
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();
}
}
在上面的示例中,我们将key序列化为Redis原生的字符串类型,将value序列化为Jackson2JsonRedisSerializer,可以支持所有类型的对象序列化。
Protobuf序列化
Protobuf是Google开发的一种轻量级高效的序列化框架,可以将对象序列化为一个字节数组。相对于Java默认的序列化方式和JSON格式序列化,Protobuf序列化后的对象占用空间更小,序列化性能更快。
以下是使用Protobuf序列化的示例:
public class ProtobufSerializer<T> implements RedisSerializer<T> {
private final Protobuf.Schema<T> schema;
public ProtobufSerializer(Protobuf.Schema<T> schema) {
this.schema = schema;
}
public byte[] serialize(T t) {
if (t == null) {
return null;
}
return ProtobufIOUtil.toByteArray(t, schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
}
public T deserialize(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
T t = schema.newMessage();
ProtobufIOUtil.mergeFrom(bytes, t, schema);
return t;
}
}
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new ProtobufSerializer<>(User.getSchema()));
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new ProtobufSerializer<>(User.getSchema())));
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();
}
}
在上面的示例中,我们自定义了一个ProtobufSerializer来序列化对象,需要传入Protobuf.Schema对象来指定对象类型。
示例
以下是使用各种序列化方式的示例:
@SpringBootTest
public class RedisServiceTest {
@Autowired
private RedisService redisService;
@Test
public void testSetAndGet() {
// 使用Java默认的序列化方式
User user = new User(1L, "Tom");
redisService.set("user1", user);
User result1 = (User) redisService.get("user1");
Assert.assertEquals(user.getId(), result1.getId());
Assert.assertEquals(user.getName(), result1.getName());
// 使用JSON格式序列化
redisService.set("user2", user, Duration.ofMinutes(10));
User result2 = (User) redisService.get("user2");
Assert.assertEquals(user.getId(), result2.getId());
Assert.assertEquals(user.getName(), result2.getName());
// 使用Protobuf序列化
redisService.set("user3", user, Duration.ofMinutes(10));
User result3 = (User) redisService.get("user3");
Assert.assertEquals(user.getId(), result3.getId());
Assert.assertEquals(user.getName(), result3.getName());
}
}
在上面的示例中,我们创建了一个User对象,分别使用Java默认的序列化方式、JSON格式序列化和Protobuf序列化。可以看到,三种序列化方式都能正确地将对象序列化和反序列化。另外,使用JSON格式序列化和Protobuf序列化时,序列化后的对象占用空间明显更小。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringDataRedis入门和序列化方式解决内存占用问题小结 - Python技术站