最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

观热点:使用springboot cache + redis缓存时使用gzip压缩以提升性能

来源:博客园


(相关资料图)

背景

在高并发的场景中,我们通常会使用缓存提升性能。在使用springboot cache时,我们通常会使用基于JSON的序列化与反序列化。

JSON具有可读性强,结构简单的特点,使用灵活。

但是JSON体积大,占用redis内存,同时增加网络开销,使用gzip压缩可以将体积缩减到原来的十分之以下,取得媲美Protobuf的编码效率

使用springboot cache + redis并使用Gzip压缩

引入依赖

            org.springframework.boot            spring-boot-starter-data-redis                            org.springframework.boot            spring-boot-starter-cache        

Gzip压缩工具类

public class GzipUtil {    public static byte[] compress(byte[] data) throws IOException {        if (data == null || data.length == 0) {            return new byte[0];        }        ByteArrayOutputStream out = new ByteArrayOutputStream();        GZIPOutputStream gzOut = new GZIPOutputStream(out);        gzOut.write(data);        gzOut.close();        return out.toByteArray();    }        public static byte[] decompress(byte[] gzip) throws IOException {        if (gzip == null || gzip.length == 0) {            return new byte[0];        }        ByteArrayInputStream in = new ByteArrayInputStream(gzip);        GZIPInputStream gzIn = new GZIPInputStream(in);        return gzIn.readAllBytes();    }    }

继承GenericJackson2JsonRedisSerializer 并实现Gzip压缩

public class JacksonGzipSerializer extends GenericJackson2JsonRedisSerializer {        @Override        public byte[] serialize(@Nullable Object source) throws SerializationException {            byte[] raw = super.serialize(source);            try {                return GzipUtil.compress(raw);            } catch (IOException ioe) {                throw new SerializationException("Exception", ioe);            }        }        @Override        public Object deserialize(@Nullable byte[] source) throws SerializationException {            try {                byte[] raw = GzipUtil.decompress(source);                return deserialize(raw, Object.class);            } catch (IOException ioe) {                throw new SerializationException("Exception", ioe);            }        }    }

配置Config,使用上述自定义的序列化及反序列化机制

@Configurationpublic class CacheConfig implements CachingConfigurer {    @Resource    private RedisConnectionFactory redisConnectionFactory;        @Override    @Bean    public CacheManager cacheManager() {        return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory), redisCacheConfiguration());    }    public RedisCacheConfiguration redisCacheConfiguration() {        return RedisCacheConfiguration.defaultCacheConfig()                .entryTtl(Duration.ofMinutes(5))                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new JacksonGzipSerializer()));    }}

使用@EnableCaching开启缓存

@SpringBootApplication@EnableCachingpublic class RedisCacheApplication {    public static void main(String[] args) {        SpringApplication.run(RedisCacheApplication.class, args);    }}

最后别忘了配置redis(具体格式和springboot版本有关)

spring.redis.database=0spring.redis.host=127.0.0.1spring.redis.port=6379spring.redis.password=

效果

没用使用gzip的大小101KB使用gzip压缩后的大小 14KB

关键词: 反序列化 压缩工具 编码效率