ERR hash value is not an integer

HINCRBY

浏览数业务

  • 使用了redis
  • spring中的RedisTemplate
    • 增加浏览数量
//简单的获取浏览数量,然后加一
Long previewNumber = getPreviewNumber(sourceId, previewType);
String key = getKey(previewType, sourceId);
previewNumber = previewNumber < 0 ? 0L : previewNumber + 1;
redisTemplate.opsForHash().put(PRIVIEW_KEY, key, previewNumber);
  • 获取浏览数
//获取缓存数量,不存在,设置为-1
private Long getCacheNumber( Map<String, Long> map, PreviewType previewType,Object sourceId) {
    String key = getKey(previewType, sourceId.toString());
    Long number = map.get(key);
    return null == number ? -1 :number;
}
//获取如果cacheNumber小于0
Long cacheNumber = getCacheNumber(map,previewType, sourceId);
if (cacheNumber < 0) {
    cacheNumber = 0L;
    Preview preview = previewDao.getPreview(previewType.getCode(), sourceId);
    if (null != preview) {
        number = preview.getNumber();
        //缓存不存在,数据库存在, 添加缓存
        hashOperations.put(PRIVIEW_KEY, getKey(previewType, sourceId), number);
    } else {
        //没有浏览记录,增加缓存为 0的记录
        hashOperations.put(PRIVIEW_KEY, getKey(previewType, sourceId), number);

    }
}
return cacheNumber;

这什么烂代码!是的,改下,起码用redis 的 increment 来做增加数量

开始给自己挖坑

做了简单的修改

Long number =  redisTemplate.opsForHash().increment(THUMB_UP_KEY, getKey(previewType, sourceId), 1);

error


Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR hash value is not an integer

调用个简单的方法也报错?

debug

Alt pic

jedis直接调用了redis的hincrby命令,没什么可说的。

Alt pic

然后直接调用getIntegerReply获取redis服务器返回的信息

Alt pic

直接是minus_byte类型

Alt pic

抛出了异常,发生了什么?

找到了如下资料

https://jira.spring.io/browse/DATAREDIS-103

应该是和序列化有关系的。
使用redis 会配置对应的key和value序列化方式。

例如:

RedisTemplate<String, String> temp = new RedisTemplate<String, String>();
temp.setKeySerializer(new StringRedisSerializer());
temp.setValueSerializer(new StringRedisSerializer());

但是不应该啊,存储到redis使用什么序列化方式,获取时肯定是用对应方式反序列化嘛,
问题应该不是出在这里。

代码注意到这里

Alt pic

spring直接调用了connection,并没有对delta进行序列化操作,接着点进去看到,

Alt pic

jedis提供的connection直接转换成String,然后使用String的getBytes();方法

Alt pic

然后看了下对应key再redis的数据

Alt pic

搞了个新key

Alt pic

原因很明显了

  • increment 会直接对值进行做增加操作,不会使用对应的redistemplate中设置的序列化方式
  • 原来redis中的旧数据是通过redisTemplate.opsForHash().put进去的,会先通过设置的序列化方式进行序列化,
  • 后面对key进行increment redis没办法对应value转成long进行操作,所以返回了ERR hash value is not an integer异常信息。

    删除旧数据就可以了吧。

    清空redis数据后

    //这里出现了异常
    hashOperations.entries(PRIVIEW_KEY)


    org.springframework.data.redis.serializer.SerializationException: fst-deserialization-error; nested exception is java.io.IOException: java.lang.NullPointerException

    原因和上面大同小异,这里获取的时候依然会进行序列化操作,而且increment设置的值是没有进行对应序列化的。这里是FST 进行反序列化时异常。

    总结

  • increment使用要避免和其他需要经过序列化的操作混用。
  • 对用到的东西要有全面的了解,才能避免各种坑。
  • 为什么会这么累,就是喜欢给自己挖坑。
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值