Spring Redis - Indexes not deleted after main entry expires

后端 未结 2 392
暗喜
暗喜 2020-12-31 13:40

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

相关标签:
2条回答
  • 2020-12-31 13:46

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-31 13:59

    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:

    1. If you run a console application just to insert data and terminate, then the expiry removes the hashes but does not perform the index cleanup since your application is not running anymore. Any events published by Redis are transient, and if your application is not listening, then these events are lost
    2. If you have enabled repository support with just @EnableRedisRepositories (without enabling keyspace-events), then the Keyspace event listener is not active, and Spring Data Redis is not subscribed to any expiry events.
    0 讨论(0)
提交回复
热议问题