RedisTemplate 中序列化方式辨析

在Spring Data Redis中,RedisTemplate 是操作Redis的核心类,它提供了丰富的API来与Redis进行交互。由于Redis是一个键值存储系统,它存储的是字节序列,因此在使用RedisTemplate时,需要指定键(Key)和值(Value)的序列化方式。不同的序列化方式适用于不同的场景。下面将详细介绍几种序列化方法。

序列化如下对象

User 类

public class User implements Serializable {String name;String ID;@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", ID='" + ID + '\'' +'}';}public User(String name, String ID) {this.name = name;this.ID = ID;}public User() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getID() {return ID;}public void setID(String ID) {this.ID = ID;}
}

JdkSerializationRedisSerializer

JdkSerializationRedisSerializer 是使用JDK自带的序列化机制(ObjectOutputStream 和 ObjectInputStream)来序列化和反序列化POJO对象。这种序列化方式会将对象转换成字节序列,并存储在Redis中。这是RedisTemplate中默认的序列化策略之一(但通常不是推荐用于生产环境的默认策略,因为JDK序列化通常效率较低且生成的字节序列较大)。最大的缺点就是:要求序列化的对象要求继承Serializable类,这是DTO无法容忍的一个要求。

优点:
  • 与其他两个比几乎没有优点,超级不推荐!
缺点:
  • 二进制形式存储,不利于查看!94 bytes
  • 序列化生成的字节序列较大,导致网络传输和存储成本较高。
  • 序列化速度慢。
  • 序列化的字节序列是私有的,不便于跨语言或跨平台共享。
代码示例
@Testpublic void test4(){User user = new User("李白","123456");//        GenericToStringSerializer<Object> genericToStringSerializer = new GenericToStringSerializer<>(Object.class);
//        redisTemplate.setKeySerializer(genericToStringSerializer);
//        JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
//        redisTemplate.setValueSerializer(jdkSerializationRedisSerializer);redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.java());// 记录开始时间Instant start = Instant.now();redisTemplate.opsForValue().set("test4",user);User user2 = (User)redisTemplate.opsForValue().get("test4");logger.info(user2.toString());// 记录结束时间Instant end = Instant.now();// 计算运行时间long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");}

在这里插入图片描述

StringRedisSerializer

StringRedisSerializer 是最简单的序列化器,它直接将字符串(或任何可以转换为字符串的数据)作为字节序列存储,不需要进行任何特殊的序列化操作。它适用于键或值为字符串的场景。

优点:
  • 效率高,不需要额外的序列化/反序列化开销。
  • 易于理解和维护。
缺点:
  • 只能用于字符串数据。

Jackson2JsonRedisSerializer

Jackson2JsonRedisSerializer 是基于Jackson库实现的JSON序列化器,它可以将Java对象序列化成JSON格式的字符串,并存储在Redis中。Jackson是一个流行的JSON处理库,提供了丰富的API来序列化和反序列化Java对象。

优点:
  • User 对象不需要实现 Serializable接口。
  • 生成的JSON格式易于阅读和调试。
  • 序列化后的数据相对较小,传输和存储效率较高,64 bytes。
  • 支持复杂的Java对象,包括嵌套对象和集合。
@Test
public void test3(){User user = new User("李白","123456");redisTemplate.setKeySerializer(RedisSerializer.string());
//        Jackson2JsonRedisSerializer<User> userJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(User.class);
//        redisTemplate.setValueSerializer(userJackson2JsonRedisSerializer);redisTemplate.setValueSerializer(RedisSerializer.json());// 记录开始时间Instant start = Instant.now();redisTemplate.opsForValue().set("test3",user);User user2 = (User)redisTemplate.opsForValue().get("test3");logger.info(user2.toString());// 记录结束时间Instant end = Instant.now();// 计算运行时间long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");
}

在这里插入图片描述

GenericFastJsonRedisSerializer

GenericFastJsonRedisSerializer 是基于Fastjson库实现的JSON序列化器,与JacksonJsonRedisSerializer类似,但它使用的是Fastjson库。Fastjson是另一个流行的JSON处理库,以其高性能著称。

优点:
  • 序列化性能高。
  • 支持复杂的Java对象。
  • 生成的JSON格式易于阅读和调试。
缺点:
  • 可能存在安全漏洞(历史版本中曾发现过安全问题,使用时需注意版本),据测试,FastJson性能不能完全超过Json库,建议生产中别用!。
    @Testpublic void test5(){User user = new User("杜甫","123456");redisTemplate.setKeySerializer(RedisSerializer.string());GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);// 记录开始时间Instant start = Instant.now();redisTemplate.opsForValue().set("test5",user);User user2 = (User)redisTemplate.opsForValue().get("test5");logger.info(user2.toString());// 记录结束时间Instant end = Instant.now();// 计算运行时间long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");}

在这里插入图片描述

总结

  • 可读性:JacksonJsonRedisSerializerGenericFastJsonRedisSerializer 皆可
  • 内存占用:GenericFastJsonRedisSerializer 59 bytes 小于 JacksonJsonRedisSerializer 60 bytes 小于 JdkSerializationRedisSerializer 94 bytes。
  • 耗时:JacksonJsonRedisSerializerGenericFastJsonRedisSerializer 差不多 且 都比 JdkSerializationRedisSerializer

生产环境中,无脑选择JacksonJsonRedisSerializer即可!

总的来说,在选择序列化器时,应根据具体的应用场景和需求来决定使用哪种序列化方式。对于大多数基于Spring Boot和Spring Data Redis的项目,推荐使用JacksonJsonRedisSerializer 来序列化和反序列化Java对象,因为它们提供了灵活性和高性能。

嵌套对象测试

    public Map<String, List<User>> getNestedObj(){ArrayList<User> users = new ArrayList<>();for (int i = 0; i < 100; i++) {users.add(new User(UUID.randomUUID().toString().substring(0,8),UUID.randomUUID().toString()));}HashMap<String, List<User>> nestedObj = new HashMap<>();nestedObj.put("one",users);return nestedObj;}

JdkSerializationRedisSerializer

    @Testpublic void test11(){Map<String, List<User>> nestedObj = getNestedObj();redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.java());// 记录开始时间Instant start = Instant.now();redisTemplate.opsForValue().set("test11",nestedObj);// 记录结束时间Instant end = Instant.now();// 计算运行时间long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");// 从redis获取nestedObj并反序列化Map<String, List<User>> nestedObj2 = (Map<String, List<User>>)redisTemplate.opsForValue().get("test11");logger.info(nestedObj2.toString());}

在这里插入图片描述

JacksonJsonRedisSerializer

    @Testpublic void test12(){Map<String, List<User>> nestedObj = getNestedObj();redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.json());// 记录开始时间Instant start = Instant.now();redisTemplate.opsForValue().set("test12",nestedObj);// 记录结束时间Instant end = Instant.now();// 计算运行时间long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");// 从redis获取nestedObj并反序列化Map<String, List<User>> nestedObj2 = (Map<String, List<User>>)redisTemplate.opsForValue().get("test12");logger.info(nestedObj2.toString());}

在这里插入图片描述

GenericFastJsonRedisSerializer

 @Testpublic void test13(){Map<String, List<User>> nestedObj = getNestedObj();redisTemplate.setKeySerializer(RedisSerializer.string());GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);// 记录开始时间Instant start = Instant.now();redisTemplate.opsForValue().set("test13",nestedObj);// 记录结束时间Instant end = Instant.now();// 计算运行时间long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");// 从redis获取nestedObj并反序列化Map<String, List<User>> nestedObj2 = (Map<String, List<User>>)redisTemplate.opsForValue().get("test13");logger.info(nestedObj2.toString());}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netgear WN604 downloadFile.php 信息泄露漏洞复现(CVE-2024-6646)

0x01 产品简介 NETGEAR WN604是一款由NETGEAR(网件)公司生产的无线接入器(或无线路由器)提供Wi-Fi保护协议(WPA2-PSK, WPA-PSK),以及有线等效加密(WEP)64位、128位和152位支持,保障网络安全。同时支持MAC地址认证、802.1x RADIUS以及EAP TLS、TTLS、PEAP等安全机制,…

Flat Ads:金融APP海外广告投放素材的优化指南

在当今全球化的数字营销环境中,金融APP的海外营销推广已成为众多金融机构与开发者最为关注的环节之一。面对不同地域、文化及用户习惯的挑战,如何优化广告素材,以吸引目标受众的注意并促成有效转化,成为了广告主们亟待解决的问题。 作为领先的全球化营销推广平台,Flat Ads凭借…

超简易高效的 AI绘图工具—与sd-webui一致界面,6G显存最高提升75%出图速率!(附安装包)

大家好&#xff0c;我是灵魂画师向阳 今天给大家分享一个基于Stable Diffusion WebUI 构建的AI绘图工具—sd-webui-forge&#xff0c;该工具的目标在于简化插件开发&#xff0c;优化资源管理&#xff0c;加速推理。 Forge承诺永远不会对Stable Diffusion WebUI用户界面添加不…

获奖案例回顾|基于卫星遥感和无人机的水稻全流程风险减量项目

引言 在现代农业保险领域&#xff0c;技术创新是推动行业进步的关键。珈和科技与太平财险的合作&#xff0c;旨在利用先进的卫星遥感和无人机技术&#xff0c;解决传统农业保险面临的诸多挑战&#xff0c;从而提升保险效率和服务质量。本次分享的项目案例获得了《金融电子化》…

启动yarn后,其他节点没有NodeManager

写在前面&#xff1a; 这个问题虽然折磨了我两天&#xff0c;但是原因特别蠢&#xff0c;可能与各位不一定一样&#xff0c;我是因为ResourceManager的节点的"/etc/hadoop/workers"文件没有配置好&#xff08;没有配hadoop102和hadoop104&#xff09;&#xff0c;但排…

数字图像处理(实践篇)四十八 PCA主成分分析降维与图像重建

目录 一 PCA 二 实践 实践① 实践② 一 PCA 主成分分析(PCA)是一种常见的数据分析技术,它可以用于降维和特征提取。 PCA 的作用包括以下几个方面: ①数据降维:PCA 可以将高维数据降维到低维空间中,从而方便后续的数据分析和可视化。可以将具有多个变量的数据集降维…

循环结构(二)——while语句【互三互三】

文章目录 &#x1f341;引言 &#x1f341;一、语句格式 &#x1f341;二、语句执行过程 &#x1f341;三、格式举例 &#x1f341;四、例题 &#x1f449;【例1】 &#x1f48e;【示例代码】 &#x1f449;【例2】 &#x1f680;【方法1】&#xff1a; &#x1f48e…

【Java伴学笔记】Day-02 变量|计算机的存储方式|数据类型|标识符|键盘输入流

一、变量 在Java中&#xff0c;变量用于存储数据值&#xff0c;可以是数字、文本或其他类型的信息。Java中的变量必须声明后才能使用&#xff0c;并且每个变量都有特定的类型。下面是一些基本的变量使用示例&#xff1a; 声明一个整型变量并赋值&#xff1a; int myNumber; …

企业如何选择渲染农场?渲染100邀请码1a12

渲染农场能降低企业成本&#xff0c;帮助企业更好的服务客户&#xff0c;那么如何选择渲染农场呢&#xff1f;又有什么标准&#xff1f;这次我们就来看下。 1、渲染性能 渲染性能是衡量农场优劣的重要指标&#xff0c;性能越好农场越优质&#xff0c;性能主要包括渲染速度、稳…

一文快速接入银行卡识别API

银行卡识别API 能通过机器学习和图像识别技术来解析银行卡相关信息&#xff0c;根据用户上传卡片自动识别内容&#xff0c;返回该卡的卡号、所属银行及银行类型等信息。可以在用户需要输入银行卡等相关信息时使用该功能&#xff0c;帮助用户快速输入正确信息&#xff0c;简化用…

VPX3U架构+GPU景嘉微:基于飞腾处理器的全国产化刀片式板卡

近期承接了客户一个全国产的VPX3U的项目。搭载的飞腾FT2000系列处理器的VPX3U板卡。服务于某某部门。这款产品拥有全国产化及自主可控的硬件技术。以下是基于飞腾FT2000处理器的VPX3U主板的一些特点&#xff1a; ①飞腾FT2000系列处理器 处理器&#xff1a;板卡兼容飞腾FT2000…

【触摸屏】【红十字会学习系统】功能模块:视频 + AI拍照合成

项目背景 提升公众急救能力&#xff1a;确保每个人都能在紧急情况下采取正确的急救措施&#xff0c;减少伤害&#xff0c;挽救生命。培养人道主义价值观&#xff1a;通过教育和培训&#xff0c;传播红十字精神&#xff0c;促进社会对弱势群体的关注与支持。建立社区响应网络&a…

【Linux】进程间通信(IPC)——匿名管道

目录 为什么要进行进程间通信&#xff1f; 匿名管道的具体实现 pipe创建内存级文件形成管道 pipe的简单使用 匿名管道的四种情况和五种特性 四种情况 五种特性 PIPE_BUF 命令行管道 | 功能代码&#xff1a;创建进程池 为什么要进行进程间通信&#xff1f; 1.数据传输&…

第五天安全笔记(持续更新)

第五天防御笔记 NAT种类&#xff1a; 静态NAT动态NATNapt 特点&#xff1a; 一对多----easy ip 多对多的napt 服务器的映射关系: 1.源NAT----基于IP地址进行转换&#xff0c;包括静态NAT&#xff0c;动态NAT&#xff0c;以及NAPT 2.目标NAT---基于目标IP地址进行转换&a…

[笔记.AI]AI Agent理解(LLM AI Agent)

前几天看到一个图&#xff0c;感觉能帮助理解 AI Agent 的基本思想和原理&#xff0c;特摘过来备忘。顺道加上自己目前对相关部分的理解&#xff0c;不一定对&#xff0c;权当做个记录。 另外&#xff0c;专门查了下图的来源&#xff0c;应该是源自 Lilian Weng 的博客文章《…

Android Studio启动报错:The emulator process for AVD Pixel_5_API_30 has terminated

Android Studio启动AVD报错&#xff1a; The emulator process for AVD Pixel_5_API_30 has terminated. 原因&#xff1a;安装时使用自定义安装后&#xff0c;修改了默认安装目录。 而avd文件默认在 C:\Users\用户名\.android 目录下。所以导致打开AVD时报错。 解决方法&am…

SadTalker数字人服务器部署

一、单独SadTalker部署 git clone https://github.com/OpenTalker/SadTalker.gitcd SadTalker conda create -n sadtalker python3.8conda activate sadtalkerpip install torch1.12.1cu113 torchvision0.13.1cu113 torchaudio0.12.1 --extra-index-url https://download.pyto…

快速上手绿联私有云UGOS Pro系统Docker | 安装/部署/管理/docker-compose一网打尽

快速上手绿联私有云UGOS Pro系统Docker | 安装/部署/管理/docker-compose一网打尽 哈喽小伙伴们好&#xff0c;我是Stark-C~ 因为众所周知的原因&#xff0c;关于最新发布的绿联私有云UGOS Pro系统咱这里也不过多说&#xff0c;不过有一点不可否认&#xff1a;新系统专业性更…

代码随想录第51天|单调栈

42. 接雨水 参考 思路1: 暴力解法 找每个柱子的左右高度超时 O(N^2) 思路2: 双指针优化 class Solution { public:int trap(vector<int>& height) {vector<int> lheight(height.size(), 0);vector<int> rheight(height.size(), 0);lheight[0] hei…

nginx的正向与反向代理

正向代理与反向代理的区别 虽然正向代理和反向代理都涉及代理服务器接收客户端请求并向服务端转发请求&#xff0c;但它们之间存在一些关键的区别&#xff1a; 正向代理&#xff1a; 在正向代理中&#xff0c;代理服务器代表客户端向服务器发送请求&#xff0c;并将服务…