这个问题几乎让我抓狂!我使用Spring Redis模板作为Redis客户端门户来管理Redis中的缓存项 . 最近我尝试在其中存储一些重要数据(过期时间大约是60秒),但有时(偶尔)它会在几秒钟之后被删除而没有任何迹象!我一次又一次检查我的代码,没有其他删除条目 . 我做了很多实验,发现只有一堆原因:1 . 当我的网络应用程序启动时,大约前五分钟,这种现象经常发生(概率大约是1/3),但在那之后,一切都还可以 . 2.设置后立即检索数据始终是正确的,即使在错误情况下也是如此 . 但几秒钟后,它就消失了 . 是的,您可能会想到我的代码中必须存在其他一些删除操作 . 我仔细检查了,答案是否定的:( .

我的spring-redis.xml的内容如下:

<bean id="parentJedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" abstract="true"
    p:timeout="50"
    p:database="0">
    <constructor-arg index="0" ref="sentinelConfig"/>
    <constructor-arg index="1" ref="jedisPoolConfig"/>
 </bean>
<bean id="jedisConnFactory" parent="parentJedisConnFactory" />
<bean id="nullSupportedRedisCacheTemplate" 
    class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnFactory">
    <property name="keySerializer">  
        <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
    </property>
    <property name="valueSerializer">
        <bean class="com.***.KryoRedisSerializer"/>
    </property>
</bean>

以下是Redis客户端实现:

@Repository("redisCache")
public class RedisCache implements Cache{

    @Autowired
    @Qualifier("nullSupportedRedisCacheTemplate")
    private RedisTemplate<String, Object> nullSupportedRedisCacheTemplate; 

    private ValueOperations<String, Object> opsValue;


    @PostConstruct
    public void init(){  
        opsValue = nullSupportedRedisCacheTemplate.opsForValue(); 
    }

    @Override
    public <T> void set(String key, T obj) { 
         set(key, obj, StaticConfiguration.DEFAULT_EXPIRE_TIME);  
    }

    @Override
    public <T> void set(String key, T obj, long expireTime) { 
        opsValue.set(key, obj, expireTime,  TimeUnit.MILLISECONDS); 
        nullSupportedRedisCacheTemplate.expire(key,  expireTime,  TimeUnit.MILLISECONDS);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T get(String key) {
        return (T) opsValue.get(key);
    }

    @Override
    public void remove(String key) {
        nullSupportedRedisCacheTemplate.delete(key);
    }

    @Override
    public <T> void asynSet(String key, T obj) {
        asynSet(key, obj, StaticConfiguration.DEFAULT_EXPIRE_TIME);
    }

    @Override
    public <T> void asynSet(String key, T obj, long expireTime) {
        opsValue.set(key, obj, expireTime,  TimeUnit.MILLISECONDS); 
        nullSupportedRedisCacheTemplate.expire(key,  expireTime,  TimeUnit.MILLISECONDS);
    }

    @Override
    public void asynRemove(String key) {
        nullSupportedRedisCacheTemplate.delete(key);
    }

    @Override
    public boolean contain(String key) {
        return nullSupportedRedisCacheTemplate.hasKey(key);
    }

}

或者您可能怀疑内存已满并且maxmemmory-policy会自动删除密钥 . 然而根据操作人员的反馈,Redis的峰值内存大约为500M,而Redis的最大内存设置为4G .

任何原因或分析将非常感谢:)