springboot2.x +redis使用和源码分析三(序列化器)

腾讯会议视频过期了怎么办?亲测可用:用这个免费插件抢救你的会议录制与回放 本文提供了三种亲测有效的腾讯会议视频过期恢复方案,包括浏览器缓存提取、专业工具组合及预防性措施。特别推荐使用免费插件抢救过期会议录制与回放,帮助职场人解决重要视频资料丢失的难题。 阅读详情

 

目录

1:spring-redis中提供的默认序列化器

1.1:StringRedisSerializer

1.2:JdkSerializationRedisSerializer

1.3:Jackson2JsonRedisSerializer

1.4:GenericJackson2JsonRedisSerializer

1.5:GenericToStringSerializer

1.6:自定义序列化器

2:各主要序列化器demo代码及序列化效率测试

3:总结:


1:spring-redis中提供的默认序列化器

了解spring提供的序列化器有助于我们针对不同需求使用最优的序列化器,虽然默认的JdkSerializationRedisSerializer基本可以满足我们的需求。

所有关于springboot有关的序列化器都在spring-data-redis包的serializer子包中,如图所示:

这里主要说明使用较多的序列化器:

1.1:StringRedisSerializer

StringRedisTemplate中默认序列化器,用于简单的string类型序列化

1.2:JdkSerializationRedisSerializer

用于序列化java对象,使用该序列化器,被序列化对象必须实现Serializable接口,最终落地到redis中数据不仅仅包含属性数据还包含一些类变量信息用于反序列化时可以正常转变为对象。所以导致可读性很差,并且落地redis的数据体量较大,浪费redis内存资源。

1.3:Jackson2JsonRedisSerializer

将java中Object序列化为json,最终保存到redis中数据为json字符串,但是使用该序列化器依赖于jackson,本质是通过jackson中objectMapper对象提供的writeValueAsBytes()与readValue()来进行序列化与反序列化。因为落地redis中数据是json字符串,所以可读性好,最终数据体量较小。但该序列化器存在一个缺点无法反序列化类型为List(或其它集合类型)带有泛型的对象。Jackson2JsonRedisSerializer进行反序列化list时其中存放是LinkedHashMap,所以当我们使用带有泛型的对象的list接受时就会出现java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to ... 类型转换异常。

1.4:GenericJackson2JsonRedisSerializer

和上述Jackson2JsonRedisSerializer相同点在于:也是将java中对象序列化为json,也是依赖与jackson,本质也是通过jackson中objectMapper对象提供的writeValueAsBytes()与readValue(里面参数不一样)来进行序列化与反序列化。而不同在于GenericJackson2JsonRedisSerializer在处理存储的类型为List(或其它集合类型)等带有泛型的对象时可以正常反序列,这是因为GenericJackson2JsonRedisSerializer在序列化时会将一些反序列化时的类信息保存在其中,而Jackson2JsonRedisSerializer只会存储json原数据,也是因为多加这写类信息导致在序列化的速度是要低于Jackson2JsonRedisSerializer

1.5:GenericToStringSerializer

 和StringRedisSerializer作用类型,不同在于GenericToStringSerializer可以将java对象现转换为字符串之后再进行序列化,而StringRedisSerializer对于需要进行序列只能要求为string类型。但经过测试发现,虽然GenericToStringSerializer入参中可以指定对象类型,但目前默认只正常8大基础类型转换,若入参为java对象则发生org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [。。。] to type [java.lang.String]异常

1.6:自定义序列化器

实现RedisSerializer接口,自己来实现适用于本身需求的序列器

2:各主要序列化器demo代码及序列化效率测试

测试代码:

 /**
     * 使用不同序列化器存储redis数据
     * @return
     */
    @RequestMapping("serializerTest")
    public  Map<String,Object> serializerTest(){

        PersonInfo personInfo = new PersonInfo();
        personInfo.setUserId("1");
        personInfo.setAge(18);
        personInfo.setName("小花");
        personInfo.setSex("女");

        List<PersonInfo> personInfos = Collections.singletonList(personInfo);

        String keyName = "serializerTest_";

        //使用StringSerializer序列话key

        StopWatch stopWatch = new StopWatch();

        redisTemplate.setKeySerializer(new StringRedisSerializer());

        String taskName = "task_";
        stopWatch.start(taskName+"StringRedisSerializer");
        for (int i=0;i<100;i++){
            //StringRedisSerializer 序列化
            redisTemplate.setValueSerializer(new StringRedisSerializer());
            redisTemplate.opsForValue().set(keyName+"StringRedisSerializer"+i, JSONObject.toJSONString(personInfos));
        }
        stopWatch.stop();

        stopWatch.start(taskName+"Jackson2JsonRedisSerializer");
        for (int i=0;i<100;i++){
            //使用Jackson2JsonRedisSerializer序列器 序列化
            redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
            redisTemplate.opsForValue().set(keyName+"Jackson2JsonRedisSerializer"+i,personInfos);
        }
        stopWatch.stop();

        stopWatch.start(taskName+"JdkSerializationRedisSerializer");
        for (int i=0;i<100;i++){
            //使用JdkSerializationRedisSerializer序列器 序列化
            redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
            redisTemplate.opsForValue().set(keyName+"JdkSerializationRedisSerializer"+i,personInfos);
        }
        stopWatch.stop();

        stopWatch.start(taskName+"GenericJackson2JsonRedisSerializer");
        for (int i=0;i<100;i++){
            //使用GenericJackson2JsonRedisSerializer序列器 序列化
            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            redisTemplate.opsForValue().set(keyName+"GenericJackson2JsonRedisSerializer"+i,personInfos);
        }
        stopWatch.stop();

        stopWatch.start(taskName+"GenericToStringSerializer");
        for (int i=0;i<100;i++){
            //GenericToStringSerializer序列化器 序列化
            redisTemplate.setValueSerializer(new GenericToStringSerializer<String>(String.class));
            //s
            redisTemplate.opsForValue().set(keyName+"GenericToStringSerializer"+i, JSONObject.toJSONString(personInfos));
        }
        stopWatch.stop();

        //打印使用不同序列化器执行时间结果
        System.out.println(stopWatch.prettyPrint());

        Map<String,Object> map = new HashMap<>(2);
        map.put("success",true);
        map.put("data",1);

        return map;
    }

上述测试代码测试了5种序列化器的下的执行效率,每次写入100次数据,随机测试5次得到以下结果:

第一次:
StopWatch '': running time = 1757843969 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
394704271  022%  task_StringRedisSerializer
454614614  026%  task_Jackson2JsonRedisSerializer
264084771  015%  task_JdkSerializationRedisSerializer
361995244  021%  task_GenericJackson2JsonRedisSerializer
282445069  016%  task_GenericToStringSerializer
第二次:
StopWatch '': running time = 1436306976 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
267357677  019%  task_StringRedisSerializer
332845988  023%  task_Jackson2JsonRedisSerializer
257288580  018%  task_JdkSerializationRedisSerializer
322376729  022%  task_GenericJackson2JsonRedisSerializer
256438002  018%  task_GenericToStringSerializer
第三次:
StopWatch '': running time = 1553815955 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
274423175  018%  task_StringRedisSerializer
350550436  023%  task_Jackson2JsonRedisSerializer
255580651  016%  task_JdkSerializationRedisSerializer
364450737  023%  task_GenericJackson2JsonRedisSerializer
308810956  020%  task_GenericToStringSerializer
第四次:
StopWatch '': running time = 1393176866 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
280269100  020%  task_StringRedisSerializer
300631014  022%  task_Jackson2JsonRedisSerializer
246369052  018%  task_JdkSerializationRedisSerializer
310196075  022%  task_GenericJackson2JsonRedisSerializer
255711625  018%  task_GenericToStringSerializer
第五次:
StopWatch '': running time = 1283761835 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
242299969  019%  task_StringRedisSerializer
270059852  021%  task_Jackson2JsonRedisSerializer
238653677  019%  task_JdkSerializationRedisSerializer
279510428  022%  task_GenericJackson2JsonRedisSerializer
253237909  020%  task_GenericToStringSerializer

从上述接口可以看出 执行效率为:JdkSerializationRedisSerializer>GenericToStringSerializer>StringRedisSerializer>GenericJackson2JsonRedisSerializer>Jackson2JsonRedisSerializer

3:总结:

  1. 如果我们要求低延时不考虑redis内存空间可以使用JdkSerializationRedisSerializer

  2. 如果redis的内存空间很宝贵而不追求低延时可以考虑Jackson2JsonRedisSerializer或GenericToStringSerializer或StringRedisSerializer,当然后两种需求我们先将对象自己转变为json格式
  3. 如果取两种中间态可以考虑使用GenericToStringSerializer序列化器
FATFS挂载多个存储设备(2):功能配置及功能测试 本文介绍了基于FATFS文件系统实现多存储设备挂载的方法,包含底层设备驱动函数编写、功能配置、功能测试。 阅读详情

相关推荐

天融信防火墙NGFW4000(TG-4628)安装配置笔记

配置一台全新的天融信防火墙NGFW4000,配置完后,内网用户10.10.1.0/24和10.10.2.0/24可以通过防火墙上网,外网用户可以通过访问防火墙的外网接口地址来访问内网的WEB服务器10.10.1.200,并且内网用户也可以通过WEB服务器的外网地址进行访问。 网络说明: 防火墙外网接口地址:218.90.123.121/30 防火墙内网接口地址:19...

weixin_33671935的博客 4456

【SpringData】了解SpringData Redis 的序列化器

SpringData Redis序列化器介绍

weixin_42369773的博客 403

线上专利申请(超详细)| 签名确认

在【法人登录】页面点击【证书登录】按钮,弹出证书登录提示框,点击【确 认】按钮,进入到输入证书密码页面,点击【取消】按钮,取消本次操作。企业在提交申请时,需要增加签名,如使用企业账户点击提交,会弹出“法人、代理机构不能签名,请使用经办人签名”,这个时候就需要换个账号了。在需要签名时,将专利官网的登录方式点击法人登录,选择扫码登录,使用移动端经办人账户的扫一扫功能扫描登录。登录完成后,再点击签名,使用移动端扫一扫功能,扫描签名,输入证书号,确认签名,并提交。最后,祝大家的申请都成功!

weixin_62112323的博客 9112

[RedisTemplate方法详解]

RedisTemplate方法详解

weixin_50391597的博客 4833

task5:在本地搭建大模型(ollama 和 LM studio 对比),接入 openclaw

关于大模型,大家千万不要想着在本地部署,根本不可行,没有那个财力。另外大模型迭代快,不可能每周都在下载大模型。再次,还是国外的模型好用,国内的模型真的在 deepresearch 上就有很大问题,你们懂的。所以本篇文章,还是聚焦在探索层面+实操,并不会实战。

这里是 AI 食用指南,持续分享有用的AI 实操和应用! 1971

鱼眼相机矫正实战:除了棋盘格,试试横向展开和经纬度法(OpenCV4/C++实现对比)

本文对比了鱼眼相机矫正的三种主流方法:棋盘格标定法、横向展开法和经纬度法,通过OpenCV4/C++实战代码解析,帮助开发者在自动驾驶、VR全景拼接和安防监控等场景中选择最适合的技术方案。重点分析了各方法的精度、处理速度和适用场景,为工程实践提供实用指导。

weixin_29032489的博客 284

Redis之RedisTemplate配置方式(序列和反序列化)(八)

POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前默认的序列化策略。:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。

zwj1030711290的优快云 9382

保姆级教程:用AdGuard DNS代理实现全设备广告过滤(含Win/Mac/安卓/iOS配置)

本文提供了一份详尽的AdGuard DNS代理配置指南,帮助用户在全设备(Win/Mac/安卓/iOS)上实现广告过滤。通过系统级DNS设置,AdGuard能有效拦截广告、跟踪器和恶意网站,提升隐私保护和浏览效率。教程涵盖原理说明、各平台配置步骤及高级优化技巧,适合不同技术水平的用户。

weixin_42656416的博客 824

Redis之RedisTemplate配置方式(序列和反序列化)

这篇文章主要介绍了Redis之RedisTemplate配置方式(序列和反序列化),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教 目录 RedisTemplate配置序列和反序列化 简介一下 实践 RedisTemplate序列化问题 序列化与反序列化规则不一致,导致报错 解决办法 总结 RedisTemplate配置序列和反序列化 对于redis操作,springboot进行了很好的封装,那就是spring data redis。提供

u013733643的博客 1万+

电子电器架构 --- OEM企标中规定ECU启动时间的目的

电子电器架构 --- OEM企标中规定ECU启动时间的目的

Soly_kun的博客 223

基于 ESP32 的智慧图书馆图书定位与借阅管理系统

本文设计的基于 ESP32 的智慧图书馆图书定位与借阅管理系统,以低成本、模块化、易部署为核心优势,融合 UWB 精准定位、RFID 自动识别、WiFi 无线通信技术,解决了传统图书馆的痛点问题。

weixin_42300449的博客 99

Spring Boot2.X(一)使用Spring Cache + Redis 实现缓存

一、Spring Cache介绍 二、Spring Boot集成Spring Cache + Redis

欢迎来到【战羽】的博客 2483

【实验必备】对AffectNet数据集进行人脸对齐的小Demo

本文首先简单介绍了AffectNet数据集,及人脸关键点等背景知识,接着Po出了人脸对齐的代码及效果展示。注:本文代码参考自FG2021的Emotion-GCN的开源代码,具有一定的可靠性,欢迎大家学习!

信小海 2670

SpringBoot 2.0 之使用声明式注解简化缓存

原文https://my.oschina.net/u/3773384/blog/1795296 SpringBoot 2.X中使用缓存注解时,发现某些配置方面与SpringBoot 1.X有些异同,这里作为第一篇博客记录下来。 1.创建SpringBoot 2.0.1 工程,引入spring-boot-starter-data-redis依赖 2.配置redis的连接属性 sp...

machao0903的专栏 514

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

springboot2.x +redis使用和源码分析二(RedisTemplate)

目录 序言:本文讲述RedisTemplate对象如何构建以及该对象对于redis提供的功能的支持 1:定义RedisTemplate 2:基本使用Ddemo 3:RedisTemplate对Pipelined支持 4:RedisTemplate对事务支持 5:RedisTemplate对Lua语言支持 5.1:使用内置字符串形式 5.2:以文件的形式 5.3:使用Lua的一些应...

F_Hello_World的博客 1239

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

5.1.7 NoSQL数据库-Redis(键值key-value)-SpringBoot整合Redis

1.写在前面 springboot 2.x后 ,原来使用的 Jedis 被 lettuce 替换。 jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式 lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数量,更像NIO模式 源码分析: 2.导入依赖 <dependency> <groupId>org.springframework.b...

敲代码的乔帮主 363

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Jedis以及SpringBoot整合Redis

什么是jedis 是官方推荐的java连接开发工具!使用java操作Redis中间件,如果要用java操作redis,那么一定要对jedis十分熟悉。 jedis的使用: 1.导入jedis依赖 Maven Repository: redis.clients » jedis » 4.1.1 (mvnrepository.com) 2.编码测试 连接数据库 操作命令 断开连接 ...

Xiezhihao_的博客 1906

springboot中集成redis

在spring boot集成redis只需要导redis的启动器就可以了。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 1、创建项目并测试 1、创建一个springboot项目 2、添加redis启动器 3、如

butcher的博客 384

linux下springboot整合 redis

linux下springboot整合 redis 一、安装redis 1.下载redis安装包 版本6以下 2.解压安装包: tar -zxvf redis-3.2.1.tar.gz 3.进入解压的目录进行编译:make 4.出现以下信息表示编译成功 . 5.编译成功后执行:sudo make install 6.redis 已经安装成功了redis 的相关命令都存放在…/redis-3.2.1/src 目录下,同时在/usr/local/bin/ 目录下生成了如下文件7. 二、配置redis 1.vim

m0_49929446的博客 546

Redis的两种JSON的序列化器 GenericToStringSerializer和Jackson2JsonRedisSerializer

Redis的两种JSON的序列化器 GenericToStringSerializer和Jackson2JsonRedisSerializer 今天springboot整合redis时出现了Could not read JSON: Can not deserialize instance of com.springboot.entities.User out of START_ARRAY token错误,研究了半天才解决,想和大家分享一下。 以下内容为枯燥的源码解读,用GenericToStringSeri

qq_42339356的博客 2934

springboot2.0 序列化方式详解, @Cacheable乱码,以及GenericToStringSerializer VS Jackson2JsonRedisSerializer

最近研究(GenericToStringSerializer VS Jackson2JsonRedisSerializer)的对比,网上查了查资料,这里记录一下,有一些修改。 前言 sprintboot 1.x.x的版本时默认使用的jedis客户端, 现在是sprintboot 2.x.x版本默认使用的lettuce客户端,两种客户端的区别如下: Jedis和Lettuce都...

zzhongcy的专栏 2548

Redis中的序列化

Redis中的序列化为什么要序列化:序列化最终的目的是为了对象可以跨平台存储,和进行网络传输,凡是需要进行“跨平台存储”和”网络传输”的数据,都需要进行序列化。优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。但缺点也非常致命,那就是此类的构造函数中有一个类型参数,优点是反序列化时不需要提供类型信息( class ),还有序列化后的结果非常庞大,是JSON格式的5倍左右,必须提供要序列化对象的类型信息( .class对象)。使用JDK提供的序列化功能。

m0_62206496的博客 665

Redis 序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer

当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedisTemplate默认使用的是StringRedisSerializer。 Spring Data JPA为我们提供了下面的Serializ...

xiaolyuh的专栏 4万+

Redis的基本应用

Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(key-value)数据库。

Z_DOUBLE_Y的博客 1197

Redis几种序列化方式,以及代码

2. GenericToStringSerializer:这种序列化方式可以将任意对象转换为字符串进行存储。但是,它的缺点是存储的结果非常庞大,大约是JSON格式的5倍左右,这会消耗Redis服务器的大量内存。1. StringRedisSerializer:这是StringRedisTemplate默认的序列化方式。它将key和value都以字符串的形式进行序列化。Redis提供了多种序列化方式来存储数据。// 输出:value。

weixin_45297084的博客 1552

redis初学笔记之三序列化

spring-data-redis的序列化类有下面这几个:GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的JacksonJsonRedisSerializer: 序列化object对象为json字符串JdkSerializationR...

TheTimeIsPassing的博客 2231
上一篇: springboot2.x +redis使用和源码分析二(RedisTemplate)
下一篇: redis中内存碎片处理
F_Hello_World
博客等级 码龄11年 38粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值