【Redis】存入redis的值,莫名其妙多了很多“\u0000”

简介: Redis缓存异常,取出的值前出现`\u0000`或部分被覆盖。问题源于误用`set(key, value, expireTime)`方法,该方法实际上按指定偏移量追加覆盖,而非设置完整值,导致额外填充`\u0000`。正确方法应为`set(key, value, timeout, TimeUnit.SECONDS)`来设置键值对和过期时间。使用重载方法时需仔细理解参数含义,避免混淆。

背景

记录在redis中的多语言缓存,突然发现取值无法正常解析,加日志后发现,从redis取出来的值,有些在正常值的前面多了很多 \u0000 ,有些值好像是覆盖原有值但没覆盖全的样子 {"key":"new Value"}lue"},导致在解析数据是报错。

定位问题

通过记录日志,发现在向redis中添加值时,值还是正常的,再取出来,就会发生这些变化,于是怀疑问题出在set方法上。

排查代码,发现代码中使用了两种set方法。

  1. set(k, v, expireTime);
  2. set(k, v, expireTime,TimeUnit.SECONDS);

这两个方法乍一看,好像是少了个设置超时时间的单位,但实际上这两个方法的功能完全不一样。

void set(K key, V value, long offset)

这个三参的方法de Jdoc如下,用指定的值,追加覆盖原有内容,追加覆盖的位置由offset确定。

Overwrite parts of key starting at the specified offset with given value.
Params:
key – must not be null.
value –
offset –

需要注意的是,如果原有内容长度不够,则会使用\u0000填充到足够的长度。

比如:现有键值对 {"test":"ABCD"}, 使用set("test","12",10),会有以下操作

ABCD不足10,所以使用 \u0000填充到长度10,即 ABCD\u0000\u0000\u0000\u0000\u0000\u0000

然后追加覆盖12, 最后的值为ABCD\u0000\u0000\u0000\u0000\u0000\u000012

这个在调试时才会看到,控制台打印出来的结果是ABCD12

void set(K key, V value, long timeout, TimeUnit unit)

这个方法才是正确的保存键值对,并设置过期时间。

Set the value and expiration timeout for key.
Params:
key – must not be null.
value – must not be null.
timeout – the key expiration timeout.
unit – must not be null.

总结

使用重载方法时,需要确认方法每个参数的含义,确认方法的功能,虽然有些参数类型是一样的,但实现的功能也会千差万别。 切记切记。

目录
相关文章
|
NoSQL Redis
go-redis 之结构体数组的存入取出
go-redis 之结构体数组的存入取出
1433 0
|
NoSQL Java 数据库连接
使用Java实现从数据库查出数据存入Redis,并在查询时先查Redis,如果Redis中没有数据再从数据库中读取
使用Java实现从数据库查出数据存入Redis,并在查询时先查Redis,如果Redis中没有数据再从数据库中读取
1267 1
|
缓存 NoSQL fastjson
Shiro Session集群共享存入Redis中SimpleSession的transient 属性不能序列化
Shiro Session集群共享存入Redis中SimpleSession的transient 属性不能序列化
446 0
|
存储 JSON NoSQL
JSON 存入 Redis
【7月更文挑战第8天】
553 12
|
NoSQL Redis
redis存入中文---的格式
redis存入中文---的格式
121 0
|
NoSQL Java Redis
redis命令行存入了数据,代码获取不到
redis命令行存入了数据,代码获取不到
204 0
|
存储 NoSQL 应用服务中间件
|
消息中间件 NoSQL 前端开发
实时统计每天pv,uv的sparkStreaming结合redis结果存入mysql供前端展示
最近有个需求,实时统计pv,uv,结果按照date,hour,pv,uv来展示,按天统计,第二天重新统计,当然了实际还需要按照类型字段分类统计pv,uv,比如按照date,hour,pv,uv,type来展示。这里介绍最基本的pv,uv的展示。
493 0
实时统计每天pv,uv的sparkStreaming结合redis结果存入mysql供前端展示
|
JSON NoSQL Java
【redis序列化】配置Jedis不需要序列化存入json 序列化Joda DateTime
【redis序列化】配置Jedis不需要序列化存入json 序列化Joda DateTime
1811 0
【redis序列化】配置Jedis不需要序列化存入json  序列化Joda DateTime
|
NoSQL Java Redis
从C++到JSON,存入redis数据库再逆序列化为JAVA。
目录 目录 一 基本原理 1原理图 二 从C序列化到JSON存入redis 1环境清单 2开始工作 3 总结归纳 三 从redis取出逆序列化为JAVA 四 声明 一 、基本原理. 1.1原理图 Created with Raphaël 2.1.0c++Json-Redis-Json Java 二 、从C++序列化到JS
2833 0