我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis Hash序列化存储的问题及解决方案

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis Hash序列化存储的问题及解决方案

这里说的是Spring Data Redis(一下简称SDR)设置Hash存储的序列化。

SDR序列化方式有多种

如:

  • StringRedisSerializer
  • JdkSerializationRedisSerializer
  • Jackson2jsonRedisSerializer
  • OxmSerializer
  • 等等

目前我有个需求,是将数据用hash的形式存到Redis数据库中,在网上搜了下实现方式,部分代码如下:

    @Bean
    public RedisTemplate<String,Object> redisTemplate(){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }

    
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setConnectionFactory(factory);
    }


    
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }

对Redis的存储设置是我自己写的

    
    public void hset(String key,String filed,Object domain){
        System.out.println("开始使用filed设置");
        hashOperations.put(key, filed, domain);
    }

    
    public Object hget(String key,String field) {
        return hashOperations.get(key, field);
    }

方法:

    @RequestMapping("/mytest")
    public Object myTest() {

        redisUtils.hset("mykey","myfield","myvalue");

       return redisUtils.hget("mykey","myfield");
    }

Hash的存储跟String有些不同,从表面上看Hash多了个field,这个自己稍微想下就可以理解了。

执行上面的代码后,用客户端查看所存储的值:

Redis Hash序列化存储的问题及解决方案

上图显示的是乱码。

用redis-cli查看:

Redis Hash序列化存储的问题及解决方案

这里显示的是我存的值myvalue前多了些东西,这是序列化的时候所加的一些东西。

执行方法时前端得到的值:

Redis Hash序列化存储的问题及解决方案

这里可见从redis中取出的值是跟我存入的完全一样的(这是因为取出的时候Spring有做反序列化处理)。

如果从redis-cli中直接存储:

host:6379> hset mykey2 myfield2 myvalue2
(integer) 1
host:6379> hget mykey2 myfield2
"myvalue2"

查看客户端中的值:

Redis Hash序列化存储的问题及解决方案

在这里存入的hash显示的是正常的。

所以我猜测之前redis桌面客户端显示“不正常”的原因应该是出在序列化的时候。

更改序列化方法

改为StringRedisSerializer方式(一般key都是字符串,所以继续使用StringRedisSerializer,这里把Hash的value序列化改为StringRedisSerializer):

    
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setConnectionFactory(factory);
    }

查看客户端的值:

Redis Hash序列化存储的问题及解决方案

这时显示OK了,redis-cli中显示的也是OK的。

所以,我们遇到的问题貌似解决了。

因为我要存储的是hash,而hashOperations为我们提供了另外一个方法putAll,这个方法支持对HashMap的操作。

代码:

    
    public void hset(String key, HashMap<String,Object> hm){
        System.out.println("开始使用hashmap设置");
        hashOperations.putAll(key,hm);
    }

因为我的hashmap中要存的值包含时间,所以就要把值设为Object,代码:

    @RequestMapping("/hm")
    public void hmsetTest() {

        HashMap<String,Object> hm =new HashMap<String,Object>();

        hm.put("myFieldKey","myFieldKey");
        hm.put("createTime",new Date());

        redisUtils.hset("mykey",hm);
    }

执行结果:

Redis Hash序列化存储的问题及解决方案

这时在调用的时候直接报错了,说是Date类型无法转String。

回到单个值存入的方法上:

    public void hset(String key,String filed,Object domain){
        System.out.println("开始使用filed设置");
        hashOperations.put(key, filed, domain);
    }

用这里执行Date的存储,结果还是包这个异常。

由此可见,使用StringRedisSerializer序列化并不能解决我们的问题,而且还有使用的限制。OxmSerializer这个东西我不太熟悉,所以没有测试。

使用Jackson2JsonRedisSerializer

更改序列化方式

redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));

执行单个日期操作结果如下:

Redis Hash序列化存储的问题及解决方案

这里显示的日期被转成时间戳形式存储的。

执行hashmap:

Redis Hash序列化存储的问题及解决方案

结果显示执行的也是成功的,如果跟StringRedisSerializer比较会发现,存储字符串的时候值得最外层会被加上“”。

继续使用JdkSerializationRedisSerializer

Redis Hash序列化存储的问题及解决方案

可以正常存储,但是显示形式一样不是我们期望的。

对于这个问题我网上有种解决方法,在redis-cli中查看的时候使用–raw指令

即启动指令为:redis-cli –raw。这种方式也可以正常的查看中文。但是查看的时候日期依然有问题,而且字符串前边会多些东西(t)。

OxmSerializer这个东西我不熟悉,所以就没有测试,但是网上一般都说建议使用JdkSerializationRedisSerializer,而且这种效率是最高的,没办法,毕竟是原生的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis Hash序列化存储的问题及解决方案

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis Hash序列化存储的问题及解决方案

目录SDR序列化方式有多种对Redis的存储设置是我自己写的更改序列化方法更改序列化方式继续使用JdkSerializationRedisSerializer这里说的是Spring Data Redis(一下简称SDR)设置Hash存储的序
2022-11-19

Redis序列化时的内存溢出问题怎么解决

Redis在进行序列化时可能会出现内存溢出的问题,主要原因是序列化的数据量过大或者是Redis服务器的内存不足。要解决这个问题,可以尝试以下几种方法:增加Redis服务器的内存。可以通过增加服务器的内存来扩大Redis可以使用的内存空间,从
Redis序列化时的内存溢出问题怎么解决
2024-04-29

redis反序列化报错原因分析以及解决方案

这篇文章主要介绍了redis反序列化报错原因分析以及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-03-15

@NonNull导致无法序列化的问题及解决

这篇文章主要介绍了@NonNull导致无法序列化的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-06

Mysql和redis缓存不一致问题的解决方案

目录一.问题描述二.解决方案1.给缓存数据设置过期时间2.缓存延时双删3.删除缓存重试机制4.读取biglog异步删除缓存三.总结一.问题描述Redis、mysql双写缓存不一致:在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓
2022-08-16

PHP开发缓存的常见问题及解决方案

PHP开发缓存的常见问题及解决方案在PHP开发过程中,为了提高网站性能和用户体验,使用缓存是常见的优化手段。然而,使用缓存也会遇到各种问题,本文将介绍PHP开发中常见的缓存问题,并提供相应的解决方案和具体代码示例。一、缓存命中率低问题描述:
PHP开发缓存的常见问题及解决方案
2023-11-07

PHP数据排序的常见问题及解决方案

PHP数据排序常见问题在PHP编程中,数据排序是一项基本而重要的任务。然而,在进行数据排序时,我们可能会遇到各种问题,这些问题可能包括性能问题、兼容性问题以及代码可读性问题等。本文将探讨一些常见的PHP数据排序问题及其解决方案。1.性能问题
PHP数据排序的常见问题及解决方案
PHP2024-12-22

SpringDataRedis入门和序列化方式解决内存占用问题小结

spring-data-redis是spring-data模块的一部分,专门用来支持在spring管理项目对redis的操作,这篇文章主要介绍了SpringDataRedis入门和序列化方式解决内存占用问题,需要的朋友可以参考下
2022-12-10

gearman队列持久化引发的问题及解决方法

本文简述了gearman用mysql持久化的方法,以及由此引发的一些问题,具体分析如下: 一、gearman 创建Mysql持久化队列的方式如下: 1. 登入mysql命令行,运行: create database gearman; 2
2022-06-04

Apache James数据库存储用户信息的密码加密问题及解决方案

ApacheJames采用MD5、SHA-1、SHA-256、SSHA和SSHA-256等加密算法来保护用户信息密码。以散列值形式存储密码,而不是明文。最佳实践包括使用强密码、定期更改密码和启用双因素身份验证。解决方案包括升级加密算法、增加盐值长度、实施哈希迭代和使用密码管理器。遵循这些措施可提高ApacheJames中密码的安全性,防止未经授权的访问。
Apache James数据库存储用户信息的密码加密问题及解决方案
2024-04-02

fastjson全局日期序列化设置导致JSONField失效问题解决方案

这篇文章主要介绍了fastjson通过代码指定全局序列化返回时间格式,导致使用JSONField注解标注属性的特殊日期返回格式失效问题的解决方案
2023-01-02

Python 列表与索引的 24 个常见问题及解决方案

今天我们要聊一聊 Python 中列表和索引的一些常见问题及其解决方案。无论你是刚刚接触 Python 的新手,还是已经有一定经验的开发者,这篇文章都会对你有所帮助。

编程热搜

目录