I am saving new entries with a Spring Data Repository. I have a TTL of 10 seconds for each entry.
When I save an entry with indexes, here is what i get in Redis
No key/values will be deleted automatically if you don't set Expiration Time.
So to automatically delete a data you have to set Expiration Time.
redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
Ref : https://redis.io/commands/expire
Below is the Spring code snippet to add a data to redis and set expiration time
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, String> template;
@Resource(name = "redisTemplate")
ValueOperations<String, String> ops;
public boolean addValue(String key, String value) {
if (template.hasKey(Constants.REDIS_KEY_PREFIX + key)) {
// key is already there
return false;
} else {
ops.set(Constants.REDIS_KEY_PREFIX + key, value);
template.expireAt(Constants.REDIS_KEY_PREFIX + key, 10);
}
return true;
}
}
Spring Data Redis Repositories use multiple Redis features to persist domain objects in Redis.
Domain objects are stored primarily in a hash (job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be
). Any expiry is applied directly to the hash so Redis can expire the key. Spring Data Redis also maintains secondary indexes (job:campaignId:aa
, job:recipient:dd
) to provide lookup by particular field values. Individual elements inside a set cannot be expired. Only the whole data structure can expire, but that's not the thing you want to do because all non-expired elements would disappear that way.
So Spring Data Redis persists a copy of the original hash as phantom hash (job:a6d6e491-5d75-4fd0-bd8e-71692f6d18be:phantom
) with a slightly longer TTL.
Spring Data Redis subscribes to key-events (with setting @EnableRedisRepositories(enableKeyspaceEvents = EnableKeyspaceEvents.ON_STARTUP
) to listen to expiry events. As soon as the original hash expires, Spring Data Redis loads the phantom hash to perform cleanups (remove references from secondary indexes).
The reason why the cleanup of your data wasn't performed can have multiple reasons:
@EnableRedisRepositories
(without enabling keyspace-events), then the Keyspace event listener is not active, and Spring Data Redis is not subscribed to any expiry events.