Sliding Expiration in Redis

2,511 views
Skip to first unread message

Pavan Kumar

unread,
Feb 22, 2016, 7:22:37 AM2/22/16
to Redis DB
Hi,

Does Redis support Sliding Expiration?

For example, if I set a key to expire in 5 minutes and if I access it after 3 minutes, then it should expire only after 5 more minutes instead of 2 minutes.

If it is not currently supported, is there any plan for adding this feature in any of the releases in the near future (if so, please share the approximate time line).

Also, could anyone please share what could be best approach to simulate sliding expiration?

Thanks in advance,
Pavan

Garry Shutler

unread,
Feb 22, 2016, 7:26:27 AM2/22/16
to redi...@googlegroups.com
Hi Pavan,

You can simulate this by sending an EXPIRE command and then do the GET. If you use pipelining you can do all this in one round-trip.

Garry


--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
To post to this group, send email to redi...@googlegroups.com.
Visit this group at https://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/d/optout.

Pavan Kumar

unread,
Feb 22, 2016, 7:40:42 AM2/22/16
to Redis DB
Hi Garry,

But I don't know what was the value of EXPIRE set originally; I am not tracking that anywhere. The new expire should be same as the original one.

Also, any chance Redis is going to provide Native Support for this in the near future?

Thanks,
Pavan

AlexanderB

unread,
Feb 22, 2016, 7:18:59 PM2/22/16
to Redis DB
This isn't currently on the road map from what I can gather, and isn't likely to be something added in the near future, as it's already possible to accomplish this with a script. 

Garry, suggestion would work great if you knew the timeout from the point of view of the redis client, but otherwise you'll need to have some memory inside of redis to track original allocation times for each item.

You could do this with a couple of lua scripts.

The first would be used in place of set (other versions would be possible for other write commands) and look something like this. 
SlidingExpireSetScript = """
local key= KEYS[1]
local value = ARGV[1]
local expiry = ARGV[2]

local valueFieldName= "data"
local expiryFieldName = "originalExpiry"

redis.call("HMSET", key, valueFieldNamevalue, expiryFieldName, expiry)
redis.call("EXPIRE", key, expiry)
"""
This stores both the original expiry and the value together in a hash, and sets the expiry. 

SlidingExpireGETScript = """
local key= KEYS[1]

local valueFieldName= "data"
local expiryFieldName = "originalExpiry"

local value = redis.call("HGET", key, valueFieldName)
local originalExpiry = redis.call("HGET", keyexpiryFieldName)

redis.call("EXPIRE", key, originalExpiry)

return value
"""

This second script will pull the original expire value the first script stored and reset it before returning the item. 
I haven't tested this, and you might need a bit more error checking to handle edge cases for things like the key having already expired, but I hope that helps if you want to go down this route. 
This should be as efficient as a native solution for all practical purposes. (Nothing here would be at all cpu bound, so the little bit of overhead from lua shouldn't have any noticeable impact vs a native solution) 

Itamar Haber

unread,
Feb 23, 2016, 5:44:59 AM2/23/16
to Redis DB
@Alexander - w/o checking the script itself for correctness, the choice of Hash is problematic. Your method is apt to create a huge data structure that only grows with every new key that's added to it. There is no sane way to do housekeeping and remove fields from the Hash once their associated TTL has passed. 


--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
To post to this group, send email to redi...@googlegroups.com.
Visit this group at https://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/d/optout.



--

Itamar Haber | Chief Developer Advocate
Redis Watch Newsletter | Curator and Janitor
Redis Labs | ~ of Redis

Mobile: +1 (415) 688 2443
Office: +1 (650) 461 4652
Mobile (IL): +972 (54) 567 9692
Office (IL): +972 (3) 720 8515 Ext. 123
Email: ita...@redislabs.com
Twitter: @itamarhaber
Skype: itamar.haber

Blog  |  Twitter  |  LinkedIn


AlexanderB

unread,
Feb 23, 2016, 1:33:55 PM2/23/16
to Redis DB
@Itamar

This script doesn't use one large hash, with many fields, but rather many hashes, each with exactly 2 fields (value + original-TTL). There's never any need to expire individual fields, as the script just expires each pair of values together stored as a hash together. 

Itamar Haber

unread,
Feb 23, 2016, 2:19:10 PM2/23/16
to Redis DB

Oh, true, jumped to conclusions without reading - sorry :)

Itamar Haber

unread,
Feb 23, 2016, 3:41:19 PM2/23/16
to Redis DB

And after reading it, your approach rules.

Reply all
Reply to author
Forward
0 new messages