Почему ключ Redis автоматически удаляется?JAVA

Программисты JAVA общаются здесь
Гость
Почему ключ Redis автоматически удаляется?

Сообщение Гость »


Я использую интерфейс CrudRepository из модуля Spring Data Redis для доступа к данным в Redis.
Моя конфигурация подключения Redis следующая:
Вот мой код:
< pre class="lang-yaml Prettyprint-override">

Код: Выделить всё

  redis:
database: 1
host: my.redis.com
port: 6380
password: redis
timeout: 5000ms
lettuce:
pool:
max-active: 50
max-idle: 10
Мой класс конфигурации Redis выглядит следующим образом:

Код: Выделить всё

@Configuration
@Slf4j
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate byteRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(RedisSerializer.byteArray());
return template;
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory)
{
RedisTemplate redisTemplate = new RedisTemplate();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//设置value hashValue值的序列化
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
serializer.setObjectMapper(om);
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashValueSerializer(serializer);
//key hasKey的序列化
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}

@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues()
.entryTtl(Duration.ofMinutes(10))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();

return redisCacheManager;
}

}
Ниже приведен класс данных, который мне нужно сохранить в Redis:

Код: Выделить всё

@Data
@AllArgsConstructor
@NoArgsConstructor
@RedisHash(RedisKeyPrefix.UNIT_CONNECT_STATUS)
@Builder
public class UnitConnectStatus implements Serializable {

@Id
private Integer unitId;
private Integer unitType;
private Boolean server2gateway;
private Boolean gateway2unit;
}
Мой класс репо написан следующим образом. Как видите, он просто расширяет CrudRepository, что очень просто. Вот почему я использую этот подход для взаимодействия с Redis:

Код: Выделить всё

public interface ConnectRepo extends CrudRepository {
}
Во всем моем проекте у меня есть только несколько методов, таких как метод saveOnline, для сохранения онлайн-статуса устройств, как показано ниже. Стоит отметить, что я использую аннотацию @Async для асинхронного хранения данных в Redis. Как видите, я не установил срок действия для значений Redis:

Код: Выделить всё

 @Async
public void saveOnline(T unit){
Assert.notNull(unit, "unit is null");
Assert.notNull(unit.getId(), "unit id is null");
connectRepo.save(UnitConnectStatus.builder()
.unitId(unit.getId())
.unitType(unit.getType())
.server2gateway(true)
.gateway2unit(true)
.build());
}

И я могу подтвердить, что в моем проекте нет кода, который выполняет действие по удалению ключа RedisKeyPrefix.UNIT_CONNECT_STATUS. Теперь происходит что-то странное. Я заметил, что во время выполнения проекта некоторые объекты unitConnectStatus иногда считываются как нулевые. Я создал простой метод тестирования воспроизведения, используя в качестве примера unitConnectStatus с id=57:

Код: Выделить всё

 @Test
public void testCon(){
for (int i = 0; i < 10000; i++) {
log.info("{}",connectRepo.findById(56).orElse(null));
Thread.sleep(200);
}
}

Код: Выделить всё

2024-01-26 11:39:48.361 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
2024-01-26 11:39:48.582 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
2024-01-26 11:39:48.803 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
2024-01-26 11:39:49.023 [][] INFO  c.t.controller.TestLeila:20  - null
2024-01-26 11:39:49.235 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
2024-01-26 11:39:49.453 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
2024-01-26 11:39:49.673 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
2024-01-26 11:39:49.906 [][] INFO  c.t.controller.TestLeila:20  - UnitConnectStatus(unitId=56, unitType=1, server2gateway=true, gateway2unit=true)
As you can see from a series of outputs, the result obtained by findById is occasionally null. In theory, there is no logic for expiration, invalidation, or deletion of my key. Why does the occasional query return null?
I don't think there should be a query for null values in my test method


Источник: https://stackoverflow.com/questions/778 ... ly-deleted

Вернуться в «JAVA»