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

Spring整合redis的key时出现\xac\xed\x00\x05t\前缀问题

@AutowiredRedisTemplate redisTemplate;User user=new User(5,"tomhs","tttt");ValueOperations opsForValue = redisTemplate.opsForValue();//存放key,opsForValue.set("user"+user.getId(),user);//读取数据;System.out.println(opsForValue.get("user" + user.getId()));

背景
项目使用Spring的RedisTemplate进行Redis数据存取操作,实际应用中发现Redis中key和value会出现“无意义”乱码前缀\xac\xed\x00\x05t\x00-(样例\xac\xed\x00\x05t\x00-abcd🔤xxxxxx:passport:associated🔑29708)。

这个乱码前缀是怎么产生的呢?有什么含义?是不是固定的?带着这三个问题,我们一探究竟。

疑问探究
怎么产生的
org.springframework.data.redis.core.RedisTemplate实例化需要序列化和反序列化组件,如果我们不指定,默认使用org.springframework.data.redis.serializer.JdkSerializationRedisSerializer进行序列化,而JdkSerializationRedisSerializer最终使用的是Java原生java.io.ObjectOutputStream.ObjectOutputStream(OutputStream)进行序列化。

这个乱码前缀就是ObjectOutputStream进行序列化时添加的。
有什么含义
\x对应0x

\xac\xed对应是0xaced,是ObjectOutputStream的序列化魔数(见java.io.ObjectStreamConstants.STREAM_MAGIC)。

\x00\x05对应是5,是ObjectOutputStream的序列化版本(见java.io.ObjectStreamConstants.STREAM_VERSION)。

这里引出一个小问题:为什么是\x00\x05而不是\x05?

因为上面2个值write时采用的是short,占2个字节。

样例乱码\x05后面有个t,不是很明显。t是转化后的ASCII码值对应字符,对应16进制是0x74,是ObjectOutputStream分配给String类型标记(见java.io.ObjectStreamConstants.TC_STRING)。

\x00-是有\x00和-组成的,是一起的,表示数据的字节数。-是转化后的ASCII码值对应字符,对应16进制是0x2d(10进制是45,样例abcd🔤xxxxxx:passport:associated🔑29708的字符数就是45,1个字符1个字节,字节数也是45)。

是不是固定的
由上面的描述可知,乱码前缀中\xac\xed\x00\x05是固定的,t在String类型情况是不变的,后面2个位(样例\x00-)是数据的字节数,是随key动态变化的。

衍生疑问
为什么显示不一样
为什么有些16进制\x显示,有些ASCII码值对应字符显示?

结合ASCII码对应的字符表,推测和显示系统能支持的字符集有关。

0x20 到 0x7e,都是比较正常的字符,可以显示出来。
字符长度超长会怎样
2个字节表示数据字节数,即最大0xffff,10进制为65535,key长度超过后会怎么样?

经试验,

key长度65535时,乱码为\xac\xed\x00\x05t\xff\xff

key长度65545时,乱码为\xac\xed\x00\x05|\x00\x00\x00\x00\x00\x01\x00\x09

t上面说过,是转化后的ASCII码值对应字符,对应16进制是0x74,是ObjectOutputStream分配给String类型标记(见java.io.ObjectStreamConstants.TC_STRING)。

|也是转化后的ASCII码值对应字符,对应16进制是0x7c,是ObjectOutputStream分配给长字符串类型标记(见java.io.ObjectStreamConstants.TC_LONGSTRING)。

同时,表示数据字节数的数值位数也变成了8位bigint。

综上,不用担心key长度越界。
使用全局化RedisTemplate配置即可

package com.yh.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** @author by 张晨光* @date 2023/11/13 12:06*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory factory){RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);//使用jackson进行序列化Jackson2JsonRedisSerializer jsonRedisSerializer =new Jackson2JsonRedisSerializer(Object.class);//规定序列化规则ObjectMapper objectMapper = new ObjectMapper();/*** 第一个参数指的是序列化的域,ALL指的是字段、get和set方法、构造方法* 第二个参数指的是序列化哪些访问修饰符,默认是public,ANY指任何访问修饰符*/objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//指定序列化输入的类型,类必须是非final修饰的类objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jsonRedisSerializer.setObjectMapper(objectMapper);//序列化key valueredisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(jsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}

应用
通过上面的探究,我们知道了“无意义”乱码前缀的含义。

如果我们新接手一个系统,它是这样使用RedisTemplate的。现在我们需要排查一个和缓存相关的问题,需要看下Redis中某个缓存值是否存在?

我们梳理业务组合出key,通过redis-cli尝试get key是获取不到结果的,此时我们可以根据上面规则自己生成“乱码前缀”,通过get “乱码前缀”+key 就可以判断缓存值是否存在了。
在这里插入图片描述

总结
上面使用RedisTemplate的方式是不好的,实际应用中key序列化可以采用StringRedisSerializer。这也是网上大部分文章建议的。
大部分文章只说了表象原因,没有分析更深入的原因。对从已存在数据中排查问题没有帮助,还是需要自己深究。

相关文章:

Spring整合redis的key时出现\xac\xed\x00\x05t\前缀问题

AutowiredRedisTemplate redisTemplate;User usernew User(5,"tomhs","tttt");ValueOperations opsForValue redisTemplate.opsForValue();//存放key,opsForValue.set("user"user.getId(),user);//读取数据;System.out.println(opsForValue.get…...

centos 6.10 安装 tcmalloc

安装 libunwind-1.6.2 下载地址 解压文件 cd libunwind-1.6.2 ./configure make && make install另一种方式 从 github 上下载的项目, 在执行autoreconf -i 时一直报错&#xff0c;libtool 未定义&#xff0c; 要先在当前目录执行 libtoolize&#xff0c;再执行 au…...

下载huggingface预训练模型到本地并调用

写在前面 在大模型横行的时代&#xff0c;无法在服务器上连接外网的研究僧真的是太苦逼了&#xff0c;每次想尝试类似于CLIP&#xff0c;BLIP之类的大模型都会得到“requests.exceptions.ConnectionError: (MaxRetryError("HTTPSConnectionPool(host‘huggingface.co’, …...

基于Vue+SpringBoot的天然气工程业务管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目详细录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程…...

jQuery使用echarts循环插入图表

目录 jQuery动态循环插入echarts图表 y轴显示最大值和最小值 x轴只显示两个值&#xff0c;开始日期和结束日期 jQuery动态循环插入echarts图表 html .center_img_list 是我们循环数据的地方 <div class"center_img shadow"><div class"center_img_b…...

二十三种设计模式全面解析-迭代器模式进阶篇:探索变体与扩展

在前文中&#xff0c;我们深入探讨了迭代器模式的概念、原理和基本应用。然而&#xff0c;迭代器模式并不止于此&#xff0c;它还有更多的变体和扩展&#xff0c;为我们提供了更多灵活的遍历方式和功能。今天&#xff0c;我将继续带领你进入迭代器模式的进阶篇&#xff0c;探索…...

指针传2

几天没有写博客了&#xff0c;怎么说呢&#xff1f;这让我总感觉缺点什么&#xff0c;心里空落落的&#xff0c;你懂吧&#xff01; 好了&#xff0c;接下来开始我们今天的正题&#xff01; 1. ⼆级指针 我们先来看看代码&#xff1a; 首先创建了一个整型变量a&#xff0c;将…...

【机器学习】决策树算法理论:算法原理、信息熵、信息增益、预剪枝、后剪枝、算法选择

1. 决策树概念 通过不断的划分条件来进行分类&#xff0c;决策树最关键的是找出那些对结果影响最大的条件&#xff0c;放到前面。 我举个列子来帮助大家理解&#xff0c;我现在给我女儿介绍了一个相亲对象&#xff0c;她根据下面这张决策树图来进行选择。比如年龄是女儿择偶更…...

WebMvcConfigurer配置详解

一、简介 WebMvcConfigurer配置类其实是Spring内部的一种配置方式&#xff0c;采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制&#xff0c;可以自定义一些Handler&#xff0c;Interceptor&#xff0c;ViewResolver&#xff0c;MessageConverter。基于ja…...

高德地图系列(一):vue项目如何使用高德地图、入门以及基本控件使用

目录 第一章 前言 第二章 准备工作 2.1 账号注册 2.2 高德地图开发平台文档 2.3 创建应用 第三章 使用地图 3.1 地图使用步骤 3.2 理解几个地图基础控件 3.3 基础类理解 第一章 前言 小编都是在vue项目中使用高德地图的&#xff0c;每一个功能都会亲测可用之后才会…...

centos FreeXL源码编译

安装、编译 https://www.gaia-gis.it/gaia-sins/freexl-2.0.0.zip yum install -y minizip minizip-devel expat-devel ./configure --prefix/usr/local/freexl-2.0.0 make && make install 环境变量 vi /etc/ld.so.conf/usr/local/freexl-2.0.0/libldconfig -v …...

【开题报告】基于SpringBoot的教资考试学习平台的设计与开发

1.选题背景 教资考试是指为了选拔和评价教师专业素质而设立的一系列考试&#xff0c;包括教师资格证考试、教师招聘考试等。这些考试对于教师的职业发展和晋升至关重要。然而&#xff0c;教资考试的内容庞杂且繁琐&#xff0c;学习者需要进行大量的知识积累和复习备考。 当前…...

C# 将PDF文档转换为Word文档

一.开发框架&#xff1a; .NetCore6.0 工具&#xff1a;Visual Studio 2022 二.思路&#xff1a; 1.使用SHA256Hash标识文档转换记录&#xff0c;数据库已经存在对应散列值&#xff0c;则直接返还已经转换过的文档 2.数据库没有对应散列值记录的话&#xff0c;则保存上传PDF…...

海报设计必备!五个免费网站分享,让你的创意得以充分展现!

海报作为一种重要的宣传工具&#xff0c;在各种场合得到了广泛的应用。然而&#xff0c;对许多人来说&#xff0c;制作一张漂亮的海报并不容易。幸运的是&#xff0c;有许多免费的海报制作网站可以帮助人们轻松地制作出漂亮的海报。本文将分享五个优秀的免费海报制作网站。 1.…...

axios不经过全局拦截器策略

项目中使用的axios请求通常会根据项目情况进行请求拦截request和响应拦截response设置&#xff0c;比如对响应拦截的值具体值返回给调用请求部分直接使用 // 部分代码展示 const request axios.create({baseURL: /proxy/,timeout: 1000 * 600,responseType: json, }) // requ…...

Pass基础-DevOps

&#xff0c;DevOps是Dev&#xff08;开发&#xff09;和Ops&#xff08;运维/运营&#xff09;的结合&#xff0c;它将人、流程、工具、工程实践等等结合起来应用到IT价值流的实现过程中&#xff0c;是一系列原则、方法、流程、实践、工具的综合体。DevOps面向应用的全生命周期…...

k8s 对外服务之 Ingress

LB ingress //Ingress 简介 service的作用体现在两个方面&#xff0c;对集群内部&#xff0c;它不断跟踪pod的变化&#xff0c;更新endpoint中对应pod的对象&#xff0c;提供了ip不断变化的pod的服务发现机制&#xff1b;对集群外部&#xff0c;他类似负载均衡器&#xff0c;可…...

Mybatis Mapper接口和xml绑定的多种方式、内部实现原理和过程

一、绑定方式 1. XML文件方式 在Mybatis中&#xff0c;我们需要创建一个与实体类对应的Mapper接口&#xff0c;然后在该接口上添加方法&#xff0c;这些方法对应着SQL语句。然后&#xff0c;我们需要创建一个XML文件&#xff0c;这个文件中包含了SQL语句和映射关系。 例如&a…...

Unity性能优化分析篇

性能优化是游戏项目开发中一个重要环节。游戏帧率过低&#xff0c;手机发烫&#xff0c; 包体太大&#xff0c;低端机上跑不起来等, 这些都需要来做优化&#xff0c;不管过去&#xff0c;现在&#xff0c;未来&#xff0c;性能优化都是永恒的话题。 而性能优化首先要掌握的是性…...

一键帮您解决win11最新版画图工具难用问题!

&#x1f984;个人主页:修修修也 ⚙️操作环境:Windows 11 正文 自从win11更新后,新版的画图工具变得非常难用,如: 使用橡皮擦后露出背版马赛克 框住某部分拖动移动时背景露出马赛克剪贴板上图片信息无法直接插入到画图板 目前没有一个好一些的能够在软件内部解决这些问题的方…...

ESXI系统安装全流程详解:从U盘启动到网络配置

1. 制作ESXI系统U盘启动盘 准备一个容量至少8GB的U盘&#xff0c;建议使用USB3.0接口的高速U盘&#xff0c;这样写入速度会快很多。我实测过&#xff0c;用USB2.0的U盘写入一个ESXI镜像可能需要20分钟&#xff0c;而USB3.0通常5分钟就能搞定。 首先需要下载两个关键文件&#x…...

通信确定性可视化冗余现场总线技术开发白皮书(能源化工交通高可靠行业 Profibus DP CAN PROFINET EtherNet/IP SPE APL)

1.前言现场总线是工业物联网的核心支撑技术&#xff0c;但当前国际主流方案在国内应用中普遍存在开发门槛高、硬件成本高、调试维护复杂、冗余配置昂贵等问题&#xff0c;难以满足中小型自动化项目及国产控制系统对高性价比、高可靠性通信的需求。CANWeb现场总线深度融合CAN的高…...

Linux进程调度机制与性能优化实践

1. Linux进程调度概述在Linux操作系统中&#xff0c;进程调度是内核最核心的功能之一。作为一个多任务操作系统&#xff0c;Linux需要合理地分配有限的CPU资源给众多进程&#xff0c;使它们能够高效、公平地运行。理解Linux的调度机制&#xff0c;对于系统性能调优、应用开发以…...

C++高性能服务开发:忍者像素绘卷推理引擎封装

C高性能服务开发&#xff1a;忍者像素绘卷推理引擎封装 1. 为什么需要高性能推理引擎 在游戏开发领域&#xff0c;实时生成高质量像素艺术的需求正在快速增长。传统的预渲染方式无法满足玩家对个性化内容和动态场景的需求&#xff0c;而直接使用Python等脚本语言运行的AI模型…...

为什么需要虚拟摄像头?OBS-VirtualCam 3大核心价值解析

为什么需要虚拟摄像头&#xff1f;OBS-VirtualCam 3大核心价值解析 【免费下载链接】obs-virtual-cam obs-studio plugin to simulate a directshow webcam 项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam 在视频会议和在线教学中&#xff0c;你是否曾希…...

对 OS:TEP 的 MLFQ 策略的一点思考

1.SJF 调度算法SJF 没啥好说的, 书上讲的很清楚了, SJF 就是最短任务优先原则, 其设计初衷是想解决 FIFO 的糟糕的周转时间的问题.但是, 正如书上所说, 这玩意主打一个秩序井然, 只能处理所有任务同时到队列的情况, 要是某堆进程不按这套路出牌, 那 SJF 立马完蛋, 书上就有一个…...

Honey Select 2终极增强补丁:3分钟快速配置完整模组生态

Honey Select 2终极增强补丁&#xff1a;3分钟快速配置完整模组生态 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 你是否曾为《Honey Select 2》的模组安装繁…...

YOLO12模型与GitHub Actions结合:自动化测试与部署流水线

YOLO12模型与GitHub Actions结合&#xff1a;自动化测试与部署流水线 1. 引言 在目标检测项目的开发过程中&#xff0c;我们经常面临这样的挑战&#xff1a;每次修改代码后都需要手动运行测试、构建镜像、部署模型&#xff0c;这个过程既耗时又容易出错。特别是对于YOLO12这样…...

OpCore-Simplify:智能配置引擎如何破解开源系统硬件兼容性难题

OpCore-Simplify&#xff1a;智能配置引擎如何破解开源系统硬件兼容性难题 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 一、问题挑战&#xff1a;开…...

零域名部署实战:阿里云ECS与宝塔面板的IP直连建站指南

1. 为什么选择IP直连建站&#xff1f; 很多刚接触服务器部署的朋友可能会疑惑&#xff1a;为什么不用域名直接访问网站&#xff1f;其实IP直连建站特别适合以下几种场景。比如你正在开发一个内部测试项目&#xff0c;需要快速让团队成员查看效果&#xff1b;或者你要给客户演示…...