Redis - Spring Boot Redis 使用 msgpack 作为序列化
发布日期:2021-06-30 23:37:17 浏览次数:3 分类:技术文章

本文共 10194 字,大约阅读时间需要 33 分钟。

首先引入 msgpack 所需要的包

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

 

RedisConfig.java(Spring Boot Redis 配置类)

import com.fasterxml.jackson.databind.ObjectMapper;import org.msgpack.jackson.dataformat.MessagePackFactory;import org.springframework.cache.annotation.CachingConfigurerSupport;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.*;@Configuration@EnableCachingpublic class RedisConfig extends CachingConfigurerSupport {    /**     * 设置spring redis data 序列化模板     * @param factory     * @return     */    @Bean    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {        StringRedisTemplate template = new StringRedisTemplate(factory);        ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());        Jackson2JsonRedisSerializer Jackson2Serializer = new Jackson2JsonRedisSerializer(Object.class);        Jackson2Serializer.setObjectMapper(mapper);        RedisSerializer redisSerializer= Jackson2Serializer;        template.setValueSerializer(redisSerializer);        template.setKeySerializer(new StringRedisSerializer());        return template;    }    /**     * 整合spring cache     * 设置@cacheable 序列化方式     * @return     */    @Bean    public RedisCacheConfiguration redisCacheConfiguration() {        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();        configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericMsgpackRedisSerializer()));        return configuration;    }}

 

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

import com.fasterxml.jackson.annotation.JsonTypeInfo.As;import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.SerializerProvider;import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;import com.fasterxml.jackson.databind.module.SimpleModule;import com.fasterxml.jackson.databind.ser.std.StdSerializer;import java.io.IOException;import org.msgpack.core.annotations.Nullable;import org.msgpack.jackson.dataformat.MessagePackFactory;import org.springframework.cache.support.NullValue;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.SerializationException;import org.springframework.util.Assert;import org.springframework.util.StringUtils;public class GenericMsgpackRedisSerializer implements RedisSerializer {    static final byte[] EMPTY_ARRAY = new byte[0];    private final ObjectMapper mapper;    public GenericMsgpackRedisSerializer() {        this.mapper = new ObjectMapper(new MessagePackFactory());        this.mapper.registerModule((new SimpleModule()).addSerializer(new GenericMsgpackRedisSerializer.NullValueSerializer(null)));        this.mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);    }    @Override    public byte[] serialize(@Nullable Object source) throws SerializationException {        if (source == null) {            return EMPTY_ARRAY;        } else {            try {                return this.mapper.writeValueAsBytes(source);            } catch (JsonProcessingException var3) {                throw new SerializationException("Could not write JSON: " + var3.getMessage(), var3);            }        }    }    @Override    public Object deserialize(@Nullable byte[] source) throws SerializationException {        return this.deserialize(source, Object.class);    }    @Nullable    public 
T deserialize(@Nullable byte[] source, Class
type) throws SerializationException { 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) { return null; } else { try { return this.mapper.readValue(source, type); } catch (Exception var4) { throw new SerializationException("Could not read JSON: " + var4.getMessage(), var4); } } } private class NullValueSerializer extends StdSerializer
{ private static final long serialVersionUID = 2199052150128658111L; private final String classIdentifier; NullValueSerializer(@Nullable String classIdentifier) { super(NullValue.class); this.classIdentifier = StringUtils.hasText(classIdentifier) ? classIdentifier : "@class"; } @Override public void serialize(NullValue value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeStartObject(); jgen.writeStringField(this.classIdentifier, NullValue.class.getName()); jgen.writeEndObject(); } }}

 

RedisCacheRedisUtils.java(序列化工具类)

import java.util.Set;import com.fasterxml.jackson.databind.ObjectMapper;import org.msgpack.jackson.dataformat.MessagePackFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.*;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.stereotype.Component;import javax.annotation.Resource;/** * @description: redis缓存工具类 * @version:1.0 */@Componentpublic class RedisCacheUtils {    private static Logger logger = LoggerFactory.getLogger(RedisCacheUtils.class);    private final static Boolean REDIS_ENABLE = true;    @Resource    private RedisTemplate redisTemplate;    @Resource    RedisConnectionFactory redisConnectionFactory;    public RedisTemplate getRedisTemplate() {        return redisTemplate;    }    public void setRedisTemplate(RedisTemplate redisTemplate) {        this.redisTemplate = redisTemplate;    }    public RedisCacheUtils(RedisTemplate redisTemplate) {        this.redisTemplate = redisTemplate;    }    /**     * 缓存基本的对象,Integer、String、实体类等     *     * @param key   缓存的键值     * @param value 缓存的值     * @return缓存的对象        */    public boolean setCacheObject(String key, Object value) {        if (!REDIS_ENABLE) {            return false;        }        logger.debug("存入缓存 key:" + key);        try {            ValueOperations
operation = redisTemplate.opsForValue(); operation.set(key, value); return true; } catch (Exception ex) { logger.error(ex.getMessage()); return false; } } /** * 根据pattern匹配清除缓存 * @param pattern */ public void clear(String pattern) { if (!REDIS_ENABLE) { return; } logger.debug("清除缓存 pattern:" + pattern); try { ValueOperations
valueOper = redisTemplate.opsForValue(); RedisOperations
redisOperations = valueOper.getOperations(); redisOperations.keys(pattern); Set
keys = redisOperations.keys(pattern); for (String key : keys) { redisOperations.delete(key); } } catch (Exception ex) { logger.error(ex.getMessage()); return; } } /** * 根据key清除缓存 * @param key */ public void delete(String key) { if (!REDIS_ENABLE) { return; } logger.debug("删除缓存 key:" + key); try { ValueOperations
valueOper = redisTemplate.opsForValue(); RedisOperations
redisOperations = valueOper.getOperations(); redisOperations.delete(key); } catch (Exception ex) { logger.error(ex.getMessage()); return; } } /** * 获得缓存的基本对象。 * @param key 缓存键值 * @return 缓存键值对应的数据 * */ public Object getCacheObject(String key) { if (!REDIS_ENABLE) { return null; } logger.debug("获取缓存 key:" + key); try { ValueOperations
operation = redisTemplate.opsForValue(); return operation.get(key); } catch (Exception ex) { logger.error(ex.getMessage()); return null; } } /** * 获得缓存的基本对象。 * @param key 缓存键值 * @return 缓存键值对应的数据 * */ public
T getCacheObject(String key, Class
clazz) { if (!REDIS_ENABLE) { return null; } logger.debug("获取缓存 key:" + key); RedisTemplate template = new StringRedisTemplate(redisConnectionFactory); Jackson2JsonRedisSerializer Jackson2Serializer = new Jackson2JsonRedisSerializer(clazz); Jackson2Serializer.setObjectMapper(new ObjectMapper(new MessagePackFactory())); RedisSerializer redisSerializer = Jackson2Serializer; template.setValueSerializer(redisSerializer); try { ValueOperations
operation = template.opsForValue(); return (T) operation.get(key); } catch (Exception ex) { logger.error(ex.getMessage()); return null; } }}

 

启动 Spring Boot 开始测试

@RestControllerpublic class TestController {    @Resource    RedisCacheUtils redisCacheUtils;    @GetMapping("/getCache")    public Object getCache() {        List
result = redisCacheUtils.getCacheObject("list_cache", new ArrayList
>().getClass()); return result; } @GetMapping("/setCache") public Object setCache() { List
list = new ArrayList<>(); for (int i = 0; i < 100; i++) { Map map = new HashMap
(); map.put("id", i); map.put("name", "index=" + i); list.add(map); } return redisCacheUtils.setCacheObject("list_cache", list); }}
  • 缓存结果(msgpack:大小1893字节)

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

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

排名结果:msgpack > fastJson > jackson

转载地址:https://lux-sun.blog.csdn.net/article/details/117290138 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:医学小知识 - 午睡和不午睡的人,长期下来有什么区别?睡多久才健康?答案来了
下一篇:程序人生 - 库克:苹果收取 30% 佣金很合理!

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月29日 09时02分53秒