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

背景

记录在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,即 ABCDu0000u0000u0000u0000u0000u0000

然后追加覆盖12, 最后的值为ABCDu0000u0000u0000u0000u0000u000012

这个在调试时才会看到,控制台打印出来的结果是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.

总结

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

console.log("talk is cheap, show me you code.")
原文地址:https://www.cnblogs.com/mlocvery/p/14600830.html