关于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写值截图(正常)
2.2 redisTemplate读值截图(正常)
2.3 本地redis读取 (失败)
3.问题分析
3.1 redis库连接角度
首先出了这么一个问题,最先能想到的是redis连接出问题。经排查,redis服务器正常启动。ping也能收到pong反馈。排除redis库存连接问题。
3.2 redis参数角度
redis配置参数中,有一项是数据库的编号。我们知道,redis默认一共有16个库,默认是选取0号库的进行默认存储。然后,我怀疑是工程中配置的是0号库,本地redis读取的是非0号库,于是进行排查。
工程配置:
本地切换至0号库,重新读值
发现,这个角度还是不能解决问题。排除。
3.3 redisTemplate角度
既然上面两个方向,一直没能解决问题,那么,只得从redisTemlpate角度下手,看能不能找到解决办法。有没有可能因为
redisTemplate.opsForValue().set(“key12”,“Java3q”)
与
redisTemplate.opsForValue().get(“key12”)
都是属于redis的方法,有没有它俩默认遵循了某种规范,我们直观上没有看到这种规范,而恰恰这种规范在本地redis客户端库中又没有遵循,然后根据key进行查查询就查不出来了呢?
我们发现,redisTemplate在使用set方法进行存储数据时,分别对key与value进行了序列化处理,处理之后将key与value都转换成为了 byte[] 字节数组。
然后我们再看get方法。
我们发现, 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客户端存储的就十分正常。
至此,我想问题已经找到答案,那就是通过设置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;
}
}
再次存值测试
然后在redis可视化工具中看一下
最后,在本地redis可视化工具中检验一下
终于,本地redis数据库客户端成功取到了redisdTemplate存入的数值。
再者,通过本地客户端存储的数值也能通过redisTemplate取出来。
5.一句话复盘
一步一步去查,一步一步去看,发现问题越来越有眉目,然后,一不小心问题就解决了。
总之,这次是redisTemplate在进行存储的时候,需要设定序列化方式,然后存储到redis中的key与value是正常的,然后通过本地客户端进行取值的时候才能正常取出来,不然的话,存进去的是乱码,redis本地客户端根据key根本找不到目标数据。
2、本资源部分来源其他付费资源平台或互联网收集,如有侵权请联系及时处理。
SEA模板网 » 关于redisTemplate.opsForValue().set数据本地redis客户端库中查不到问题的解决记录
发表评论