4
votes

I am using redis as a cache and would like to expire data in redis that are not actively used. Currently, setting expiry for an object deletes an object after the expiry time has elapsed. However, I would like to retain the object in redis if it is read atleast once before the object expires.

One way I see is to store a separate expiry_key for every object and set the expiry to the expiry_key instead of the original object. Subscribe to del notification on the expiry_key and when a del notification is received, check if the object is read atleast once (via a separately maintained access log) during the expiry interval. If the object is not read, execute a del command on the original object. If it is read, recreate the expiry_key with the expiry interval.

This implementation requires additional systems to manage expiry and would prefer to do it locally with redis.

Are there better solutions to solve this?

Resetting expiry for the object for every read will increase the number of writes to redis and hence this is not a choice.

Note the redis cache refresh is managed asynchronously via a change notification system.

3

3 Answers

15
votes

You could just set the expiry key again after each read (setting a TTL on a key is O(1)).

It maybe make sense for your system to do this in a transaction:

MULTI
GET mykey
EXPIRE mykey 10
EXEC

You could also pipeline the commands.

This pattern is also described in the official documentation.

2
votes

Refer to section "Configuring Redis as a cache" in http://redis.io/topics/config

We can set maxmemory-policy to allkeys-lru to clear inactive content from redis. This would work for the usecase I have stated.

0
votes

Another way is do define a notification on the key , and then reset it's expiration

see here