SpringDataRedis入门和序列化方式解决内存占用问题小结

下面就是关于“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技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • MySQL读取JSON转换的方式

    MySQL 5.7及以上版本支持JSON数据类型,但在某些场景下我们需要将JSON数据进行读取、转换或者查询,以满足业务需求。 以下是MySQL读取JSON转换的方式的完整攻略: 1. 查询JSON对象的属性 可以通过箭头运算符->或->>、JSON_EXTRACT函数查询JSON对象的属性。其中,->返回JSON属性的文本格式,-&…

    Java 2023年5月26日
    00
  • 利用apache ftpserver搭建ftp服务器的方法步骤

    下面我将详细讲解利用Apache FtpServer搭建FTP服务器的方法步骤,包括以下内容: 安装Java环境 下载Apache FtpServer 配置Apache FtpServer 启动FTP服务器 如何连接FTP服务器 示例使用 1. 安装Java环境 首先需要在服务器上安装Java环境,可以到Java官网下载对应的安装包进行安装。 2. 下载Ap…

    Java 2023年5月20日
    00
  • 详细解读Hibernate的缓存机制

    详细解读Hibernate的缓存机制 Hibernate作为一个优秀的对象关系映射工具,其具有强大的缓存机制,对于提高系统性能有很大的作用。但是,如果我们不了解它的缓存机制以及所带来的优缺点,可能会导致系统性能下降,因此对于Hibernate的缓存机制需要进行详细的解读。 1. Hibernate的缓存机制 Hibernate的缓存机制可以分为三层,分别是一…

    Java 2023年5月19日
    00
  • Java中的日期和时间类以及Calendar类用法详解

    Java中日期和时间类以及Calendar类用法详解 Java中有三个主要的日期时间类:Date、Calendar和SimpleDateFormat。在Java 8及以上版本中,还增加了新的日期时间API(即java.time包)。 1. Date类 日期类java.util.Date最初设计用于表示当前时间。Date自基准时间(1970年1月1日)以来的毫…

    Java 2023年5月20日
    00
  • JVM内存增强之逃逸分析

    JVM内存增强之逃逸分析是指在Java应用程序启动时,JVM在运行过程中动态的分析程序的对象生命周期,将对象的使用范围限制在方法内部,从而达到减少对象在堆上的分配、减少GC(垃圾回收)压力、提高应用程序的性能等目的的一种技术手段。 下面是JVM内存增强之逃逸分析的完整攻略: 1. 什么是逃逸分析? 逃逸分析是一种程序优化技术,它对程序中的对象进行分析,识别出…

    Java 2023年5月19日
    00
  • Logger.error打印错误异常的详细堆栈信息

    Logger是一种Java日志框架,用于在Java应用程序中记录和输出各种事件的消息。Logger.error()方法是Logger框架中的一个方法,通常用于记录和输出错误和异常的详细信息。 要打印错误异常的详细堆栈信息,可以使用Logger.error()方法并将异常作为参数。下面是使用Logger.error()方法打印异常堆栈信息的完整攻略: 导入相关…

    Java 2023年5月27日
    00
  • JAVA 十六进制与字符串的转换

    Java 中可以通过多种方式实现十六进制和字符串之间的转化。本文将介绍两种主要的方法:使用内置类库和字节数组转换。 使用内置类库实现 Java 内置的 Integer、Long 和 Short 等类库提供了十六进制和字符串之间的转化方法。下面是一个示例: // 十六进制转字符串 int hexVal = 0x1F; String hexStr = Integ…

    Java 2023年5月27日
    00
  • SpringMVC后端返回数据到前端代码示例

    SpringMVC后端返回数据到前端代码示例的完整攻略如下: 1. 定义Controller类 首先要定义一个Controller类,用于处理前端的请求,然后返回数据给前端。以下是示例代码: @RestController @RequestMapping("/api") public class UserController { @Aut…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部