当前位置: 首页 > news >正文

SpringDataRedis存储Redis的数据序列化

在使用Spring Data Redis存储数据至Redis时,选择合适的序列化策略至关重要。它不仅影响数据存储的效率和空间利用率,还关系到跨语言兼容性和系统的扩展性。适当的序列化方式可以确保数据正确无误地被存储和读取,提升系统的稳定性和维护性,避免由于默认序列化带来的乱码或不兼容问题,从而保障应用的高效运行和数据的安全完整。

目录

序列化介绍

问题解析

问题测试

解决方案

方案一

方案二


序列化介绍

序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。在反序列化时,这个过程是相反的,即将这些信息还原成对象。

当你将数据存储到Redis中时,如果发现数据变成字节,这通常与序列化方式有关。指在Java环境中使用Redis客户端,默认情况下会使用JDK内置的序列化方式(即Serializable接口及ObjectOutputStream等类来实现对象的序列化)。

问题解析

兼容性问题:JDK序列化格式是Java特有的,这意味着只有Java程序才能反序列化这些对象。如果你的系统中有非Java组件需要访问Redis中的数据,那么它们将无法直接读取这些序列化的对象。

性能问题:JDK序列化机制有时会比较慢,并且生成的序列化内容可能比其他序列化方法(如JSON, Protobuf, Avro等)更大,从而影响网络传输效率和存储空间。

安全性考虑:反序列化不受信任的数据源可能导致安全漏洞,例如反序列化攻击。这是因为反序列化过程会执行某些代码,如果攻击者能够控制输入流,就可能利用这一点执行恶意代码.

其实可读性也非常差(这谁能看出来name=小明, age=18是上面这一大串

问题测试

使用SpringDataRedis客户端:

创建一个测试的SpringBoot项目,引入依赖:

        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

在application.yaml加入:

spring:
  data:
    redis:
      host: localhost
      port: 6379
      password:
      lettuce:
        pool:
          max-active: 8
          min-idle: 0
          max-idle: 8
          max-wait: 1000

在测试类,加入以下代码:

@SpringBootTest
class SpringDataRedisDemoApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void testString() {
        redisTemplate.opsForValue().set("time","12");
        Object time = redisTemplate.opsForValue().get("time");
        System.out.println("time = " + time);
    }


    @Test
    void testUser() {
        redisTemplate.opsForValue().set("user",new User("小明",18));
        User user = (User) redisTemplate.opsForValue().get("user");
        System.out.println("user = " + user);
    }
}

运行后查看Java客户端工具:

解决方案

方案一

配置RedisTemplate,使用JSON作为序列化格式,实现自动序列化和反序列化。

加入下列代码,设置特定的序列化工具(GenericJackson2JsonRedisSerializer

@Configuration
public class RedisConfig {
    /**
     * RedisTemplate配置序列化规则
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);
        // 创建Json序列化工具
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置key的序列化规则
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // 设置value的序列化规则
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}

修改测试类注入的RedisTemplate类型

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

运行结果如下:

可以看到可读性大大提高,可以确保所有存储到Redis中的数据都以一种一致且易于理解的方式进行序列化和反序列化,提升了与Redis交互时的序列化效率、数据兼容性和易用性,使得存储和检索过程更加高效和直观。

方案二

方案一有一个缺点,在储存对象时,把类的class类型写入了JSON结果中,存入Redis,带来了额外的内存开销。(在大量数据的情况下可能给内存带来压力

使用StringRedisTemplate,手动实现序列化和反序列化。

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    private static final ObjectMapper mapper = new ObjectMapper();
    
    @Test
    void testUser() throws JsonProcessingException {
        //创建对象
        User user = new User("张三", 18);
        // 手动序列化
        String json = mapper.writeValueAsString(user);
        // 存入redis
        stringRedisTemplate.opsForValue().set("users",json);
        // 取出数据
        String users = stringRedisTemplate.opsForValue().get("users");
        // 手动反序列化
        User user1 = mapper.readValue(users, User.class);
        // 输出
        System.out.println("user1 = " + user1);
    }

实现效果如下:

实现了去除类的class类型,节省了内存。

相关文章:

  • centos 8安装及相关操作
  • 外层元素旋转,其包括在内的子元素一并旋转(不改变旋转中心),单元测试
  • 线程同步:多线程编程的核心机制
  • 确定一个数字是否为 2 的幂
  • 为什么 Young GC 比 Full GC 快
  • 北京迅为iTOP-RK3568开发板OpenHarmony系统南向驱动开发实操-HDF驱动配置LED
  • Muduo库的简介与使用
  • Java常用算法
  • 使用Fluent-bit将容器标准输入和输出的日志发送到Kafka
  • 序列化和反序列化TCP粘包问题
  • 性能调优与抓包分析:TCP三次握手、CDN优化与Wireshark实战
  • 【Git】配置Git
  • 软考计算机知识-流水线
  • 【云原生】动态资源分配(DRA)深度洞察报告
  • 技术速递|Visual Studio Code 2025年2月更新(v1.98)
  • 网络华为HCIA+HCIP数据链路层协议-以太网协议
  • 手写一个简易版的tomcat
  • 解释VLA和具身智能之间的关系
  • 神经网络中常用语言特性(python)(待完善)
  • 视创云展:打造沉浸式体验环境,助力企业线上营销
  • 网站建设的技术指标/百度宣传推广费用
  • 哪些网站做推广效果好/互联网产品运营
  • 郴州文明网网站/2022网络热词30个
  • 做短视频的网站/怎样优化网站
  • 青岛做网站的好公司/百度关键词排名批量查询工具
  • 厦门微信网站/代做百度首页排名