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

ken*_*y_k 3 redis jedis spring-data spring-data-redis spring-boot

我正在使用 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();
}
Run Code Online (Sandbox Code Playgroud)

我在用spring-data-redis:2.1.4

那么,是否有任何相关文档或可靠的事实来源?

ken*_*y_k 5

经过一番探索后,答案似乎与所使用的序列化器有关 - 在本例中GenericJackson2JsonRedisSerializer。不想挖掘太多,我只是编写了一个测试来验证(nil)Redis 返回的任何值都转换为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))
}
Run Code Online (Sandbox Code Playgroud)

所以,在 Redis 中,这样:

127.0.0.1:6379> MGET "\"key1\"" "\"nonexisting\""
1) "{\"@class\":\"some.package.SomeObject\",\"contentId\":\"key1\"}"
2) (nil)
Run Code Online (Sandbox Code Playgroud)

将导致List以下结果:{SomeObject, null}