spring-data-redis multiGet 如何处理缓存未命中?

Posted

技术标签:

【中文标题】spring-data-redis multiGet 如何处理缓存未命中?【英文标题】:How are cache misses handled by spring-data-redis multiGet? 【发布时间】:2020-02-10 21:44:54 【问题描述】:

我正在使用 Redis 缓存(通过 Jedis 客户端),我想使用 ValueOperations#multiGet,它接受 Collection 的键,并从缓存中返回 List 的对象,同样命令。我的问题是,当某些键在缓存中而其他键不在时会发生什么?我知道在下面使用了Redis MGET,它将为不在缓存中的任何元素返回nil

我找不到任何关于ValueOperations 将如何解释此响应的文档。我假设他们将是null,当然可以对其进行测试,但是围绕未记录的行为构建系统会很危险。

为了完整起见,这里是缓存客户端的配置方式:

@Bean
public RedisConnectionFactory redisConnectionFactory() 
    JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();

    redisConnectionFactory.setHostName(address);
    redisConnectionFactory.setPort(port);

    redisConnectionFactory.afterPropertiesSet();
    return redisConnectionFactory;


@Bean
public ValueOperations<String, Object> someRedisCache(RedisConnectionFactory cf) 
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(cf);
    redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
    redisTemplate.afterPropertiesSet();
    return redisTemplate.opsForValue();

我正在使用spring-data-redis:2.1.4

那么,有没有关于这方面的任何文档,或者一些可靠的事实来源?

【问题讨论】:

【参考方案1】:

经过一番摸索,看起来答案与使用的序列化程序有关 - 在本例中为 GenericJackson2JsonRedisSerializer。不想挖掘太多,我只是写了一个测试,验证 Redis 返回的任何(nil) 值都转换为null

@Autowired
ValueOperations<String, SomeObject> valueOperations

@Test
void multiGet() 
    //Given
    SomeObject someObject = SomeObject
            .builder()
            .contentId("key1")
            .build()
    valueOperations.set("key1", someObject)

    //When
    List<SomeObject> someObjects = valueOperations.multiGet(Arrays.asList("key1", "nonexisting"))

    //Then
    assertEquals(2, someObjects.size())
    assertEquals(someObject, someObjects.get(0))
    assertEquals(null, someObjects.get(1))

所以,在 Redis 中,这是:

127.0.0.1:6379> MGET "\"key1\"" "\"nonexisting\""
1) "\"@class\":\"some.package.SomeObject\",\"contentId\":\"key1\""
2) (nil)

将产生ListSomeObject, null

【讨论】:

您好!所以你的意思是说,redis 缓存为不存在的键返回 null 已经是内置的。我们不必担心,我们可以检查它是否为空。

以上是关于spring-data-redis multiGet 如何处理缓存未命中?的主要内容,如果未能解决你的问题,请参考以下文章

Spring之Redis访问(Spring-data-redis)

指定与 spring-data-redis 一起使用的逻辑数据库

spring-data-redis

Spring-data-redis: serializer实例

spring-data-redis 使用过程中踩过的坑

Spring Boot + spring-data-redis