关于redisTemplate.opsForValue().set数据本地redis客户端库中查不到问题的解决记录

关于redisTemplate.opsForValue数据redis库中查不到

  • 1.问题背景
  • 2.问题截图
    • 2.1 redisTemplate写值截图(正常)
    • 2.2 redisTemplate读值截图(正常)
    • 2.3 本地redis读取 (失败)
  • 3.问题分析
    • 3.1 redis库连接角度
    • 3.2 redis参数角度
    • 3.3 redisTemplate角度
  • 4.问题解决(一大堆截图 )
  • 5.一句话复盘

1.问题背景

项目中需要使用redis缓存数据字典信息,于是将redis整合进了maven工程中,然后使用redisTemplate进行写值、读值测试,发现写、读均正常。然后在本地redis库中,通过key值读取maven工程中刚才通过redisTemplate存储的数值时,发现获取不到,于是需要研究一番,一探究竟,事情就是这么个事情。

2.问题截图

2.1 redisTemplate写值截图(正常)

(图1)(图2)

2.2 redisTemplate读值截图(正常)

(图3)

2.3 本地redis读取 (失败)

(图4)

3.问题分析

3.1 redis库连接角度

首先出了这么一个问题,最先能想到的是redis连接出问题。经排查,redis服务器正常启动。ping也能收到pong反馈。排除redis库存连接问题。
(图5)

3.2 redis参数角度

redis配置参数中,有一项是数据库的编号。我们知道,redis默认一共有16个库,默认是选取0号库的进行默认存储。然后,我怀疑是工程中配置的是0号库,本地redis读取的是非0号库,于是进行排查。
工程配置:
(图6)本地切换至0号库,重新读值
(图7)
发现,这个角度还是不能解决问题。排除。

3.3 redisTemplate角度

既然上面两个方向,一直没能解决问题,那么,只得从redisTemlpate角度下手,看能不能找到解决办法。有没有可能因为
redisTemplate.opsForValue().set(“key12”,“Java3q”)

redisTemplate.opsForValue().get(“key12”)

都是属于redis的方法,有没有它俩默认遵循了某种规范,我们直观上没有看到这种规范,而恰恰这种规范在本地redis客户端库中又没有遵循,然后根据key进行查查询就查不出来了呢?

(图8)

(图9)

(图10)

(图11)
我们发现,redisTemplate在使用set方法进行存储数据时,分别对key与value进行了序列化处理,处理之后将key与value都转换成为了 byte[] 字节数组

然后我们再看get方法。

(图12)

(图13)

(图14)
我们发现, redisTemplate的get方法在进行实际的读取数值操作的时候,首先把key转换成了byte[]格式,然后进行数据的读取。
然后到这里,貌似有一点眉目了,那就是我本地redis客户端如果想通过get.(“key12”)获取到数值的话,好像必须的先进行一些序列化的设置,然后才能正常的处理。

4.问题解决(一大堆截图 )

根据上面3.3的分析,我们貌似能确定两个解决问题的方向(如果猜想正确的话),那就是:
1、从redisTemplate入手,设置key与value相关的序列化方式等等
2、对本地redis数据库客户端进行序列化的配置,使之根据key进行get取值的时候,能够先实现类似redisTemplate.get那种把key先转换成byte[]这种格式

从开发的角度,貌似1比较容易优化和配置,毕竟redisTemplate作为一个比较厉害的redis操作利器,大概率是存在关于key与value相关的配置的。

然后,再通过redis可视化工具可以看得到,通过redisTemplate存储的数据的key与value都是乱码,而通过本地redis客户端存储的就十分正常。

(图15)至此,我想问题已经找到答案,那就是通过设置redisTemplate的key与value的序列化格式,然后,解决了乱码问题,想必便能够通过本地redis客户端进行取值了。

代码中调整redis的配置

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {

        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        //设置连接池工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //首先解决key的序列化方式
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);

        //解决value的序列化方式
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        ObjectMapper objectMapper = new ObjectMapper();
        //记住序列化类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);

        //解决jackson2无法反序列化localDateTime的问题
        objectMapper.disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;

    }
}


再次存值测试
(图16)
然后在redis可视化工具中看一下

(图17)
最后,在本地redis可视化工具中检验一下
(图18)
终于,本地redis数据库客户端成功取到了redisdTemplate存入的数值。

再者,通过本地客户端存储的数值也能通过redisTemplate取出来。
(图19)
(图20)

(图21)

5.一句话复盘

一步一步去查,一步一步去看,发现问题越来越有眉目,然后,一不小心问题就解决了。

总之,这次是redisTemplate在进行存储的时候,需要设定序列化方式,然后存储到redis中的key与value是正常的,然后通过本地客户端进行取值的时候才能正常取出来,不然的话,存进去的是乱码,redis本地客户端根据key根本找不到目标数据。

1、本站目前拥有近 1000+ 精品收费资源,现在加入VIP会员即可全部下载。
2、本资源部分来源其他付费资源平台或互联网收集,如有侵权请联系及时处理。
SEA模板网 » 关于redisTemplate.opsForValue().set数据本地redis客户端库中查不到问题的解决记录

发表评论

加入本站VIP会员订阅计划,海量资源免费查看

目前为止共有 3654 位优秀的VIP会员加入! 立刻加入VIP会员