这个问题几乎让我抓狂!我使用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 .
任何原因或分析将非常感谢:)