Quantcast
Channel: Active questions tagged redis+java - Stack Overflow
Viewing all articles
Browse latest Browse all 2204

Why is the Redis key automatically deleted?

$
0
0

I am using the CrudRepository interface from Spring Data Redis module to access data in Redis.My Redis connection configuration is as follows:Here is my code:

  redis:    database: 1    host: my.redis.com    port: 6380    password: redis    timeout: 5000ms     lettuce:      pool:        max-active: 50         max-idle: 10 

My Redis configuration class is as follows:

@Configuration@Slf4j@EnableCachingpublic class RedisConfig {    @Bean    public RedisTemplate<String, byte[]> byteRedisTemplate(RedisConnectionFactory connectionFactory) {        RedisTemplate<String, byte[]> template = new RedisTemplate<>();        template.setConnectionFactory(connectionFactory);        template.setKeySerializer(new StringRedisSerializer());        template.setValueSerializer(RedisSerializer.byteArray());        return template;    }    @Bean    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)    {        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();        //设置value hashValue值的序列化        Jackson2JsonRedisSerializer<Object> 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;    }}

The following is the data class that I need to save in Redis:

@Data@AllArgsConstructor@NoArgsConstructor@RedisHash(RedisKeyPrefix.UNIT_CONNECT_STATUS)@Builderpublic class UnitConnectStatus implements Serializable {    @Id    private Integer unitId;    private Integer unitType;    private Boolean server2gateway;    private Boolean gateway2unit;}

My repo class is written as follows. As you can see, it simply extends a CrudRepository, which is very straightforward. This is the reason I use this approach to interact with Redis:

public interface ConnectRepo extends CrudRepository<UnitConnectStatus,Integer> {}

In my entire project, I only have a few methods like the saveOnline method to save the online status of devices, as shown below. It's worth noting that I use the @Async annotation to asynchronously store data in Redis. As you can see, I haven't set an expiration time for Redis values:

 @Async public <T extends Unit>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()); }

And I can confirm that there is no code in my project that executes the action of deleting the key 'RedisKeyPrefix.UNIT_CONNECT_STATUS.' Now, something strange is happening. I've noticed that during the project's runtime, some unitConnectStatus objects occasionally appear to be read as null. I've created a simple reproduction test method using the unitConnectStatus with id=57 as an example:

 @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  - null2024-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


Viewing all articles
Browse latest Browse all 2204

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>