Redis - RedisTemplate及4种序列化方式深入解读

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis - RedisTemplate及4种序列化方式深入解读

20210216222255282.png


概述

使用Spring 提供的 Spring Data Redis 操作redis 必然要使用Spring提供的模板类 RedisTemplate, 今天我们好好的看看这个模板类 。


RedisTemplate


20210216214431352.png


看看4个序列化相关的属性 ,主要是 用于 KEY 和 VALUE 的序列化 。 举个例子,比如说我们经常会将POJO 对象存储到 Redis 中,一般情况下会使用 JSON 方式序列化成字符串,存储到 Redis 中 。


Spring提供的Redis数据结构的操作类


ValueOperations 类,提供 Redis String API 操作

ListOperations 类,提供 Redis List API 操作

SetOperations 类,提供 Redis Set API 操作

ZSetOperations 类,提供 Redis ZSet(Sorted Set) API 操作

GeoOperations 类,提供 Redis Geo API 操作

HyperLogLogOperations 类,提供 Redis HyperLogLog API 操作


StringRedisTemplate


再看个常用的 StringRedisTemplate

RedisTemplate<K, V> 支持泛型,StringRedisTemplate K V 均为String类型。


org.springframework.data.redis.core.StringRedisTemplate 继承 RedisTemplate 类,使用 org.springframework.data.redis.serializer.StringRedisSerializer 字符串序列化方式。

20210216215349631.png


RedisSerializer 序列化 接口

RedisSerializer接口 是 Redis 序列化接口,用于 Redis KEY 和 VALUE 的序列化

20210216220139708.png

RedisSerializer 接口的实现类 如下

20210216220010707.png


归类一下

  • JDK 序列化方式 (默认)
  • String 序列化方式
  • JSON 序列化方式
  • XML 序列化方式


JDK 序列化方式 (默认)


org.springframework.data.redis.serializer.JdkSerializationRedisSerializer ,默认情况下,RedisTemplate 使用该数据列化方式。


我们来看下源码 RedisTemplate#afterPropertiesSet()


20210216222750703.png

Spring Boot 自动化配置 RedisTemplate Bean 对象时,就未设置默认的序列化方式。

绝大多数情况下,不推荐使用 JdkSerializationRedisSerializer 进行序列化。主要是不方便人工排查数据。

我们来做个测试

20210216222955539.png


运行单元测试


20210216223050702.png



看不懂呀 ,老哥


KEY 前面带着奇怪的 16 进制字符 , VALUE 也是一串奇怪的 16 进制字符 。。。。。


为什么是这样一串奇怪的 16 进制? ObjectOutputStream#writeString(String str, boolean unshared) 实际就是标志位 + 字符串长度 + 字符串内容


KEY 被序列化成这样,线上通过 KEY 去查询对应的 VALUE非常不方便,所以 KEY 肯定是不能被这样序列化的。


VALUE 被序列化成这样,除了阅读可能困难一点,不支持跨语言外,实际上也没还OK。不过,实际线上场景,还是使用 JSON 序列化居多。


String 序列化方式

org.springframework.data.redis.serializer.StringRedisSerializer ,字符串和二进制数组的直接转换


20210216223557311.png

绝大多数情况下,我们 KEY 和 VALUE 都会使用这种序列化方案。


JSON 序列化方式


org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer 使用 Jackson 实现 JSON 的序列化方式,并且从 Generic 单词可以看出,是支持所有类。

public GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName) {
      .....
      ..... 
    if (StringUtils.hasText(classPropertyTypeName)) {
      mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
    } else {
      mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
    }
  }


classPropertyTypeName 不为空的话,使用传入对象的 classPropertyTypeName 属性对应的值,作为默认类型(Default Typing) ,否则使用传入对象的类全名,作为默认类型(Default Typing)。


我们来思考下,在将一个对象序列化成一个字符串,怎么保证字符串反序列化成对象的类型呢?Jackson 通过 Default Typing ,会在字符串多冗余一个类型,这样反序列化就知道具体的类型了


20210216230349348.jpg



先说个结论

  • 标准JSON
{
  "id": 100,
  "name": "小工匠",
  "sex": "Male"
}


  • 使用 Jackson Default Typing 机制序列化
{
  "@class": "com.artisan.domain.Artisan",
  "id": 100,
  "name": "小工匠",
  "sex": "Male"
}


示例

测试一把

【配置类】

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        // 创建 RedisTemplate 对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置 RedisConnection 工厂。 它就是实现多种 Java Redis 客户端接入的秘密工厂
        template.setConnectionFactory(connectionFactory);
        // 使用 String 序列化方式,序列化 KEY 。
        template.setKeySerializer(RedisSerializer.string());
        // 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
        template.setValueSerializer(RedisSerializer.json());
        return template;
    }


【单元测试】

   @Test
    public void testJacksonSerializer() {
        Artisan artisan  = new Artisan();
        artisan.setName("小工匠");
        artisan.setId(100);
        artisan.setSex("Male");
        // set
        redisTemplate.opsForValue().set("artisan", artisan);
    }



【结果】

2021021623020442.png


是不是多了@class 属性,反序列化的对象的类型就可以从这里获取到。

@class 属性看似完美解决了反序列化后的对象类型,但是带来 JSON 字符串占用变大,所以实际项目中,我们很少采用 Jackson2JsonRedisSerializer


XML 序列化方式


org.springframework.data.redis.serializer.OxmSerializer使用 Spring OXM 实现将对象和 String 的转换,从而 String 和二进制数组的转换。 没见过哪个项目用过,不啰嗦了



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
缓存 NoSQL Java
RedisTemplate操作Redis,这一篇文章就够了
redis是一款开源的Key-Value数据库,运行在内存中,由C语言编写。企业开发通常采用Redis来实现缓存。同类的产品还有memcache 、memcached 等。
242 1
|
1月前
|
存储 JSON NoSQL
[Redis]——RedisTemplate的两种序列化方式
[Redis]——RedisTemplate的两种序列化方式
|
4月前
|
缓存 NoSQL Java
Spring Data Redis对象缓存序列化问题
在使用 Redis 时,有没有遇到同我一样,对象缓存序列化问题的呢?
67 6
Spring Data Redis对象缓存序列化问题
|
4月前
|
XML 存储 JSON
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
开发时经常会遇到需要保存配置的情况,最常见的实现方式是将对象序列化成Json,再写入文件并保存到本地磁盘。 本文将使用开源库**ApeFree.DataStore**来替换原有的对象存储过程,实现一个可以随意切换存储方式的对象存储方法。 ApeFree.DataStore是一款可配置的对象存储库,支持在不同平台/介质中对内存中的对象进行存储与还原(如本地存储、注册表存储)。支持配置序列化格式(如Json、Xml),支持配置压缩算法(如GZip、Defalte),支持配置加密算法(如AES、RSA)。
68 0
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
|
4月前
|
存储 缓存 NoSQL
SpringBoot整合Redis调用lua脚本出现空指针异常(序列化器问题)
一、问题描述 业务中出现需要保证原子性的一系列缓存操作,所以决定使用lua脚本来保证原子性。 但是调用过程中lua脚本抛出了异常:attempt to perform arithmetic on local ‘xxx’ (a nil value) 发生异常的lua脚本代码(部分)
|
5月前
|
NoSQL Redis
RedisTemplate执行lua脚本在Redis集群模式下报错EvalSha is not supported in cluster environment.
RedisTemplate执行lua脚本在Redis集群模式下报错EvalSha is not supported in cluster environment.
160 0
|
16天前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
228 0
|
24天前
|
负载均衡 监控 NoSQL
Redis的集群方案有哪些?
Redis集群包括主从复制(基础,手动故障恢复)、哨兵模式(自动高可用)和Redis Cluster(官方分布式解决方案,自动分片和容错)。此外,还有如Codis、Redisson和Twemproxy等第三方工具用于代理和负载均衡。选择方案需考虑应用场景、数据规模和并发需求。
191 2
|
30天前
|
NoSQL Redis
Redis集群(六):集群常用命令及说明
Redis集群(六):集群常用命令及说明
187 0
|
2月前
|
运维 NoSQL 算法
Redis-Cluster 与 Redis 集群的技术大比拼
Redis-Cluster 与 Redis 集群的技术大比拼
82 0

热门文章

最新文章