Redis - Spring Boot Redis 使用 msgpack 作为序列化

简介: Redis - Spring Boot Redis 使用 msgpack 作为序列化

首先引入 msgpack 所需要的包

<dependency><groupId>org.msgpack</groupId><artifactId>msgpack-core</artifactId><version>0.8.13</version></dependency><dependency><groupId>org.msgpack</groupId><artifactId>jackson-dataformat-msgpack</artifactId><version>0.8.13</version></dependency>
  • 版本一定要对齐,之前 jackson-dataformat-msgpack 版本太低导致无法使用。

 

RedisConfig.java(Spring Boot Redis 配置类)

importcom.fasterxml.jackson.databind.ObjectMapper;
importorg.msgpack.jackson.dataformat.MessagePackFactory;
importorg.springframework.cache.annotation.CachingConfigurerSupport;
importorg.springframework.cache.annotation.EnableCaching;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.cache.RedisCacheConfiguration;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.data.redis.core.StringRedisTemplate;
importorg.springframework.data.redis.serializer.*;
@Configuration@EnableCachingpublicclassRedisConfigextendsCachingConfigurerSupport {
/*** 设置spring redis data 序列化模板* @param factory* @return*/@BeanpublicRedisTemplateredisTemplate(RedisConnectionFactoryfactory) {
StringRedisTemplatetemplate=newStringRedisTemplate(factory);
ObjectMappermapper=newObjectMapper(newMessagePackFactory());
Jackson2JsonRedisSerializerJackson2Serializer=newJackson2JsonRedisSerializer(Object.class);
Jackson2Serializer.setObjectMapper(mapper);
RedisSerializerredisSerializer=Jackson2Serializer;
template.setValueSerializer(redisSerializer);
template.setKeySerializer(newStringRedisSerializer());
returntemplate;
    }
/*** 整合spring cache* 设置@cacheable 序列化方式* @return*/@BeanpublicRedisCacheConfigurationredisCacheConfiguration() {
RedisCacheConfigurationconfiguration=RedisCacheConfiguration.defaultCacheConfig();
configuration=configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(newGenericMsgpackRedisSerializer()));
returnconfiguration;
    }
}

GenericMsgpackRedisSerializer.java(Spring Cache msgpack 序列化类)

importcom.fasterxml.jackson.annotation.JsonTypeInfo.As;
importcom.fasterxml.jackson.core.JsonGenerator;
importcom.fasterxml.jackson.core.JsonProcessingException;
importcom.fasterxml.jackson.databind.ObjectMapper;
importcom.fasterxml.jackson.databind.SerializerProvider;
importcom.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
importcom.fasterxml.jackson.databind.module.SimpleModule;
importcom.fasterxml.jackson.databind.ser.std.StdSerializer;
importjava.io.IOException;
importorg.msgpack.core.annotations.Nullable;
importorg.msgpack.jackson.dataformat.MessagePackFactory;
importorg.springframework.cache.support.NullValue;
importorg.springframework.data.redis.serializer.RedisSerializer;
importorg.springframework.data.redis.serializer.SerializationException;
importorg.springframework.util.Assert;
importorg.springframework.util.StringUtils;
publicclassGenericMsgpackRedisSerializerimplementsRedisSerializer<Object> {
staticfinalbyte[] EMPTY_ARRAY=newbyte[0];
privatefinalObjectMappermapper;
publicGenericMsgpackRedisSerializer() {
this.mapper=newObjectMapper(newMessagePackFactory());
this.mapper.registerModule((newSimpleModule()).addSerializer(newGenericMsgpackRedisSerializer.NullValueSerializer(null)));
this.mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
    }
@Overridepublicbyte[] serialize(@NullableObjectsource) throwsSerializationException {
if (source==null) {
returnEMPTY_ARRAY;
        } else {
try {
returnthis.mapper.writeValueAsBytes(source);
            } catch (JsonProcessingExceptionvar3) {
thrownewSerializationException("Could not write JSON: "+var3.getMessage(), var3);
            }
        }
    }
@OverridepublicObjectdeserialize(@Nullablebyte[] source) throwsSerializationException {
returnthis.deserialize(source, Object.class);
    }
@Nullablepublic<T>Tdeserialize(@Nullablebyte[] source, Class<T>type) throwsSerializationException {
Assert.notNull(type, "Deserialization type must not be null! Pleaes provide Object.class to make use of Jackson2 default typing.");
if (source==null||source.length==0) {
returnnull;
        } else {
try {
returnthis.mapper.readValue(source, type);
            } catch (Exceptionvar4) {
thrownewSerializationException("Could not read JSON: "+var4.getMessage(), var4);
            }
        }
    }
privateclassNullValueSerializerextendsStdSerializer<NullValue> {
privatestaticfinallongserialVersionUID=2199052150128658111L;
privatefinalStringclassIdentifier;
NullValueSerializer(@NullableStringclassIdentifier) {
super(NullValue.class);
this.classIdentifier=StringUtils.hasText(classIdentifier) ?classIdentifier : "@class";
        }
@Overridepublicvoidserialize(NullValuevalue, JsonGeneratorjgen, SerializerProviderprovider) throwsIOException {
jgen.writeStartObject();
jgen.writeStringField(this.classIdentifier, NullValue.class.getName());
jgen.writeEndObject();
        }
    }
}

RedisCacheRedisUtils.java(序列化工具类)

importjava.util.Set;
importcom.fasterxml.jackson.databind.ObjectMapper;
importorg.msgpack.jackson.dataformat.MessagePackFactory;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.core.*;
importorg.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
importorg.springframework.data.redis.serializer.RedisSerializer;
importorg.springframework.stereotype.Component;
importjavax.annotation.Resource;
/*** @description: redis缓存工具类* @version:1.0*/@ComponentpublicclassRedisCacheUtils {
privatestaticLoggerlogger=LoggerFactory.getLogger(RedisCacheUtils.class);
privatefinalstaticBooleanREDIS_ENABLE=true;
@ResourceprivateRedisTemplateredisTemplate;
@ResourceRedisConnectionFactoryredisConnectionFactory;
publicRedisTemplategetRedisTemplate() {
returnredisTemplate;
    }
publicvoidsetRedisTemplate(RedisTemplateredisTemplate) {
this.redisTemplate=redisTemplate;
    }
publicRedisCacheUtils(RedisTemplateredisTemplate) {
this.redisTemplate=redisTemplate;
    }
/*** 缓存基本的对象,Integer、String、实体类等** @param key   缓存的键值* @param value 缓存的值* @return缓存的对象   */publicbooleansetCacheObject(Stringkey, Objectvalue) {
if (!REDIS_ENABLE) {
returnfalse;
        }
logger.debug("存入缓存 key:"+key);
try {
ValueOperations<String, Object>operation=redisTemplate.opsForValue();
operation.set(key, value);
returntrue;
        } catch (Exceptionex) {
logger.error(ex.getMessage());
returnfalse;
        }
    }
/*** 根据pattern匹配清除缓存* @param pattern*/publicvoidclear(Stringpattern) {
if (!REDIS_ENABLE) {
return;
        }
logger.debug("清除缓存 pattern:"+pattern);
try {
ValueOperations<String, Object>valueOper=redisTemplate.opsForValue();
RedisOperations<String, Object>redisOperations=valueOper.getOperations();
redisOperations.keys(pattern);
Set<String>keys=redisOperations.keys(pattern);
for (Stringkey : keys) {
redisOperations.delete(key);
            }
        } catch (Exceptionex) {
logger.error(ex.getMessage());
return;
        }
    }
/*** 根据key清除缓存* @param key*/publicvoiddelete(Stringkey) {
if (!REDIS_ENABLE) {
return;
        }
logger.debug("删除缓存 key:"+key);
try {
ValueOperations<String, Object>valueOper=redisTemplate.opsForValue();
RedisOperations<String, Object>redisOperations=valueOper.getOperations();
redisOperations.delete(key);
        } catch (Exceptionex) {
logger.error(ex.getMessage());
return;
        }
    }
/*** 获得缓存的基本对象。* @param key 缓存键值* @return 缓存键值对应的数据*   */publicObjectgetCacheObject(Stringkey) {
if (!REDIS_ENABLE) {
returnnull;
        }
logger.debug("获取缓存 key:"+key);
try {
ValueOperations<String, Object>operation=redisTemplate.opsForValue();
returnoperation.get(key);
        } catch (Exceptionex) {
logger.error(ex.getMessage());
returnnull;
        }
    }
/*** 获得缓存的基本对象。* @param key 缓存键值* @return 缓存键值对应的数据*   */public<T>TgetCacheObject(Stringkey, Class<T>clazz) {
if (!REDIS_ENABLE) {
returnnull;
        }
logger.debug("获取缓存 key:"+key);
RedisTemplatetemplate=newStringRedisTemplate(redisConnectionFactory);
Jackson2JsonRedisSerializerJackson2Serializer=newJackson2JsonRedisSerializer(clazz);
Jackson2Serializer.setObjectMapper(newObjectMapper(newMessagePackFactory()));
RedisSerializerredisSerializer=Jackson2Serializer;
template.setValueSerializer(redisSerializer);
try {
ValueOperations<String, T>operation=template.opsForValue();
return (T) operation.get(key);
        } catch (Exceptionex) {
logger.error(ex.getMessage());
returnnull;
        }
    }
}

启动 Spring Boot 开始测试

@RestControllerpublicclassTestController {
@ResourceRedisCacheUtilsredisCacheUtils;
@GetMapping("/getCache")
publicObjectgetCache() {
List<String>result=redisCacheUtils.getCacheObject("list_cache", newArrayList<HashMap<String, String>>().getClass());
returnresult;
    }
@GetMapping("/setCache")
publicObjectsetCache() {
List<Map>list=newArrayList<>();
for (inti=0; i<100; i++) {
Mapmap=newHashMap<String, String>();
map.put("id", i);
map.put("name", "index="+i);
list.add(map);
        }
returnredisCacheUtils.setCacheObject("list_cache", list);
    }
}
  • 缓存结果(msgpack:大小1893字节)

image.png

  • 缓存结果(fastjson:大小2781字节)

image.png

  • 速度比较(10000条数据测试,非专业测试结果,仅供参考)

排名结果:msgpack > fastJson > jackson

image.png

目录
相关文章
|
NoSQL 安全 Java
深入理解 RedisConnectionFactory:Spring Data Redis 的核心组件
在 Spring Data Redis 中,`RedisConnectionFactory` 是核心组件,负责创建和管理与 Redis 的连接。它支持单机、集群及哨兵等多种模式,为上层组件(如 `RedisTemplate`)提供连接抽象。Spring 提供了 Lettuce 和 Jedis 两种主要实现,其中 Lettuce 因其线程安全和高性能特性被广泛推荐。通过手动配置或 Spring Boot 自动化配置,开发者可轻松集成 Redis,提升应用性能与扩展性。本文深入解析其作用、实现方式及常见问题解决方法,助你高效使用 Redis。
1373 4
|
8月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
689 5
|
9月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
804 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
11月前
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
799 2
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
383 32
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
839 0
|
存储 人工智能 NoSQL
SpringBoot整合Redis、ApacheSolr和SpringSession
本文介绍了如何使用SpringBoot整合Redis、ApacheSolr和SpringSession。SpringBoot以其便捷的配置方式受到开发者青睐,通过引入对应的starter依赖,可轻松实现功能整合。对于Redis,可通过配置RedisSentinel实现高可用;SpringSession则提供集群Session管理,支持多种存储方式如Redis;整合ApacheSolr时,借助Zookeeper搭建SolrCloud提高可用性。文中详细说明了各组件的配置步骤与代码示例,方便开发者快速上手。
261 11
|
NoSQL Java API
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Spring Boot 集成 Redis
本文介绍了在Spring Boot中集成Redis的方法,包括依赖导入、Redis配置及常用API的使用。通过导入`spring-boot-starter-data-redis`依赖和配置`application.yml`文件,可轻松实现Redis集成。文中详细讲解了StringRedisTemplate的使用,适用于字符串操作,并结合FastJSON将实体类转换为JSON存储。还展示了Redis的string、hash和list类型的操作示例。最后总结了Redis在缓存和高并发场景中的应用价值,并提供课程源代码下载链接。
2776 0
深入实践springboot实战 蓄势待发 我不是雷锋 我是知识搬运工
springboot,说白了就是一个集合了功能的大类库,包括springMVC,spring,spring data,spring security等等,并且提供了很多和可以和其他常用框架,插件完美整合的接口(只能说是一些常用框架,基本在github上能排上名次的都有完美整合,但如果是自己写的一个框架就无法实现快速整合)。
|
Java 数据安全/隐私保护
Neo4j【付诸实践 01】SpringBoot集成报错org.neo4j.driver.exceptions.ClientException:服务器不支持此驱动程序支持的任何协议版本(解决+源代码)
Neo4j【付诸实践 01】SpringBoot集成报错org.neo4j.driver.exceptions.ClientException:服务器不支持此驱动程序支持的任何协议版本(解决+源代码)
953 1

热门文章

最新文章