0

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 :)

  • 1
    Sounds like either an open Redis server (security) or eviction (memory policies, TTL). Could you post the parts of your code where you write to Redis? – mp911de Jun 28 '16 at 09:41
  • Already updated. Thanks for your response. – Little Bird Jun 28 '16 at 12:06
  • Thank mp911de. You are right, it is the problem of memory policies (volatile-lru), and the ops man found that some Redis instances' maxmemory is 512M (The fore feedback from him is a mistake). For important and short-lifetime data, should we use noenviction policy? – Little Bird Jun 29 '16 at 05:14
  • Eviction policy has two purposes: Free data from memory so you don't use more memory than available and get rid of data you maybe don't need. If you don't want to lose data, use no eviction and make sure you have enough memory. – mp911de Jun 30 '16 at 06:37

0 Answers0