This issue almost driven me crazy! I use spring Redis template as the Redis client portal to manage my cache items in Redis. Recently I try to store some important data in it (expire time is about 60s) , but sometimes ( occasionally) it is deleted after several seconds without any sign! I check my code again and again, no other delete entries. I took many experiments and only a litter of cause was found: 1. when the my web application started, during about the fore five minutes, the phenomenon occurs frequently (probability is about 1/3), but after that time, everything is ok. 2. Retrieving the data immediately after set is always right, even in the error situation. But after several seconds, it disappears. Yes you may think of that there must be some other delete operations exists in my codes. I have check it very carefully, and the answer is no :(.
My spring-redis.xml's content is as following:
<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>
And below is the Redis client implement:
@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);
}
}
Or you may doubt that the memory is full and maxmemmory-policy delete the key automatically. However according to the ops man's feedback, the peak memory of Redis is about 500M while the max memory of Redis is set as 4G.
Any cause or analysis from you will be highly appreciated :)