【问题标题】:Spring Data Cache + Redis: How to avoid storing class names in serialized JSON which waste lots of space?Spring Data Cache + Redis:如何避免将类名存储在序列化的 JSON 中浪费大量空间?
【发布时间】:2022-01-31 02:10:26
【问题描述】:

我正在使用使用 Redis 作为缓存管理器的 Spring Data Cache。配置如下:

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(
            RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(SerializationPair.fromSerializer(RedisSerializer.string()))
                .serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()))
        )
        .build()

让我们想象一个使用spring数据缓存的非常幼稚的例子:

@Cacheable(...)
MyPOJO compute() { ... }

但是,RedisSerializer.json() 确实是 GenericJackson2JsonRedisSerializer。因此,恕我直言,它将存储{"hello":"world","@class":"com.my.name.some.package.MyPOJO"} 之类的内容。 @class: ... 部分很长,浪费了 Redis 中的宝贵内存。此外,恕我直言,Spring Data Cache 应该足够聪明,能够意识到值类型确实是 MyPOJO,因此它不需要存储 "@class"

因此我的问题是:如何避免在 Spring Data Cache + Redis CacheManager 中将类名存储在浪费大量空间的序列化 JSON 中?

感谢您的任何建议!

【问题讨论】:

    标签: java spring redis spring-data spring-cache


    【解决方案1】:

    您是否研究过 GenericJackson2JsonRedisSerializer 的实现?看起来默认对象映射器配置为使用 Jacksons 多态类型功能。但是还有一个选项可以像这样传递自定义 ObjectMapper:

    SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper))
    

    您可以配置和传递自定义 Jacksons 对象映射器,无论是否带有类型信息。有几种方法可以配置类型信息的存储方式(如果你确实需要的话):https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization

    在早期版本中,Spring 没有配置类型信息,如下所示:How to use GenericJackson2JsonRedisSerializer 看起来这在最近的版本中已更改。但是,仍然可以根据需要配置您的序列化程序。

    【讨论】:

    • 您好,非常感谢!事实上,我曾尝试使用ObjectMapper().registerKotlinModules() 创建一个全新的对象映射器,然后,奇怪的是,它没有给出 MyPOJO,而是给出了 LinkedHashMap。我真的不知道会发生什么......
    猜你喜欢
    • 2022-08-05
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2017-06-12
    • 2015-04-29
    • 2012-06-14
    • 2013-02-25
    相关资源
    最近更新 更多