Search code examples
javaspring-bootredisspring-data-redis

Spring Data Redis does not clean up secondary Geospatial Index after TTL expiry


Using the following model:

@RedisHash("positions")
public class Position {

    @Id
    private String id;

    @GeoIndexed
    private Point coordinates;

    @TimeToLive(unit = TimeUnit.MINUTES)
    protected int ttl;

    //...
}

I noticed that some data remains persisted after the Time To Live expires. Notice the difference between keys * command before and after the expire event:

Before

127.0.0.1:6379> keys *
1) "positions:336514e6-3e52-487a-a88b-98b110ec1c28"
2) "positions:coordinates"
3) "positions:336514e6-3e52-487a-a88b-98b110ec1c28:idx"
4) "positions"
5) "positions:336514e6-3e52-487a-a88b-98b110ec1c28:phantom"

After

127.0.0.1:6379> keys *
1) "positions:coordinates"
2) "positions:336514e6-3e52-487a-a88b-98b110ec1c28:idx"
3) "positions"
4) "positions:336514e6-3e52-487a-a88b-98b110ec1c28:phantom"

Only the positions:336514e6-3e52-487a-a88b-98b110ec1c28 item was deleted.

I also notice that, after some more time, the *:phantom item also is deleted, but not the rest. Is this a bug or it is required to configure/implement something more?


Solution

  • Your application needs to stay active. Redis Repositories use keyspace events to get notified about expiration so Spring Data Redis can cleanup index structures. Redis supports expiry on top-level keys only, it does not support expiry on list/set elements.

    The :phantom key has a slightly longer expiration, that's why it expires after the original key has expired. It's used to provide the expired hash values for index cleanup and such.